Typescript 如何设置&x2018;nativescript条带’;在NativeScript Vue中

Typescript 如何设置&x2018;nativescript条带’;在NativeScript Vue中,typescript,stripe-payments,nativescript,nativescript-vue,nativescript-plugin,Typescript,Stripe Payments,Nativescript,Nativescript Vue,Nativescript Plugin,我正在尝试在我的nativescript Vue应用程序中设置«nativescript stripe»插件。在插件github上进行演示有点困难,因为它们只有Angular和TypeScript的演示。是否有人获得了使用Vue的StandardComponent,并可以告诉我要将哪些参数发送到StripeService.createPaymentSession() 我尝试在模板中设置,并在mounted()上设置paymentSession: import { StripeAddress,

我正在尝试在我的
nativescript Vue
应用程序中设置
«nativescript stripe»
插件。在插件github上进行演示有点困难,因为它们只有
Angular和TypeScript的演示。是否有人获得了使用Vue的
StandardComponent
,并可以告诉我要将哪些参数发送到
StripeService.createPaymentSession()

我尝试在模板中设置
,并在
mounted()上设置paymentSession:

import {
  StripeAddress,
  StripePaymentData,
  StripePaymentListener,
  StripePaymentMethod,
  StripePaymentSession,
  StripeShippingMethod,
  StripeShippingMethods
} from "nativescript-stripe/standard";
import { StripeService, Listener } from "~/shared/stripe/stripe.service";

var paymentSession = {};

export default {
  mounted() {
    //not sure if this is the way to do it
    paymentSession = StripeService.createPaymentSession(
      this.$refs.cartPage,
      this.stripeItem.price,
      new Listener(this)
    );
  },
在我的stripe.service.ts文件中,我得到了与Angular demo()相同的代码,只是我设置了publishableKey和backendBaseURL,并为Listener导出了一个类:

export class Listener {
  public component;
  constructor(component) {
      this.component = component;
  }
  onCommunicatingStateChanged(_isCommunicating) {
      this.component.changeDetectionRef.detectChanges();
  }
//etc. (code from https://github.com/triniwiz/nativescript-stripe/blob/master/demo-angular/app/demo/standard.component.ts)
我想也许我应该把Listener类也移到它自己的文件中,但现在不要认为这是问题所在

应用程序崩溃,并显示错误消息:

控制台错误file:///node_modules/nativescript-vue/dist/index.js:2129:21 [Vue warn]:已安装挂钩中的错误: “类型错误:\共享\条带\条带\服务\网页包\导入的\模块\ 6 \条带[“条带服务”]。createPaymentSession不是一个函数。 (在“\u shared\u stripe\u stripe\u service\u网页包\u IMPORTED\u MODULE\u 6\u[“stripe service”]”中)createPaymentSession(this.$refs.cartPage,this.stripeItem.price,new\u shared\u stripe\u stripe\u service\u网页包\u IMPORTED\u MODULE\u 6\u Listener”),“\u shared\u stripe\u stripe\u service\u网页包\u IMPORTED\u MODULE\u 6\u Listener”[“createPaymentSession”未定义)

编辑:

我终于能够使用以下设置运行应用程序:

ShoppingCart.vue:

<template>
  <Page ref="cartPage" class="page">
    <ActionBar class="action-bar">
      <NavigationButton ios:visibility="collapsed" icon="res://menu" @tap="onDrawerButtonTap"></NavigationButton>
      <ActionItem
        icon="res://navigation/menu"
        android:visibility="collapsed"
        @tap="onDrawerButtonTap"
        ios.position="left"
      ></ActionItem>
      <Label class="action-bar-title" text="ShoppingCart"></Label>
    </ActionBar>
    <StackLayout class="page p-10">
              <GridLayout rows="auto" columns="auto,*">
                <Label row="0" col="0" :text="stripeItem.name" class="h2"></Label>
                <Label
                  row="0"
                  col="1"
                  :text="'kr' + stripeItem.price"
                  class="text-right text-muted"
                ></Label>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <GridLayout
                rows="auto"
                columns="*,auto"
                @tap="showPaymentMethods()"
                class="list-group-item"
              >
                <Label row="0" col="0" text="Payment Type"></Label>
                <StackLayout row="0" col="1" orientation="horizontal">
                  <Image width="32" height="20" :src="paymentImage"></Image>
                  <Label
                    :text="paymentType"
                    class="text-right text-muted"
                    :visibility="!isLoading ? 'visible' : 'collapse'"
                  ></Label>
                </StackLayout>
                <ActivityIndicator
                  row="0"
                  col="1"
                  :busy="isLoading"
                  :visibility="isLoading ? 'visible' : 'collapse'"
                ></ActivityIndicator>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <GridLayout rows="auto" columns="auto,*" @tap="showShipping()" class="list-group-item">
                <Label row="0" col="0" text="Shipping Method"></Label>
                <Label row="0" col="1" :text="shippingType" class="text-right text-muted"></Label>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <GridLayout rows="auto" columns="auto,*" class="list-group-item">
                <Label row="0" col="0" text="Total"></Label>
                <Label row="0" col="1" :text="'kr ' + total" class="text-right"></Label>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <Label :text="errorMessage" class="text-danger" textWrap="true"></Label>
              <Button text="Buy" :isEnabled="canBuy" class="btn btn-primary btn-active" @tap="buy()"></Button>
              <ActivityIndicator
                :busy="paymentInProgress"
                :visibility="paymentInProgress ? 'visible' : 'collapse'"
              ></ActivityIndicator>
              <Label :text="successMessage" class="text-primary" textWrap="true"></Label>
              <StackLayout class="hr-light m-10"></StackLayout>
              <Label text="Debug Info"></Label>
              <Label :text="debugInfo" class="body" textWrap="true"></Label>
            </StackLayout>
  </Page>
</template>

<script>
import * as utils from "~/shared/utils";
import SelectedPageService from "../shared/selected-page-service";
import { StripeService, Listener } from "~/shared/stripe/stripe.service.ts";

const Page = require("tns-core-modules/ui/page").Page;

let stripeService = new StripeService();
var paymentSession = {};

export default {
  mounted() {
    SelectedPageService.getInstance().updateSelectedPage("ShoppingCart");

    paymentSession = stripeService.createPaymentSession(new Page(), 1213, new Listener(this));
  },
  data() {
    return {
      stripeItem: {
        id: 0,
        name: "Something to buy",
        price: 1200
      },
      paymentInProgress: false,
      canBuy: true,
      isLoading: false,
      paymentType: "",
      paymentImage: "",
      shippingType: "",
      total: "",
      debugInfo: "",
      successMessage: "",
      errorMessage: ""
    };
  },
  methods: {
    onDrawerButtonTap() {
      utils.showDrawer();
    },
    showPaymentMethods() {
      return stripeService.showPaymentMethods(paymentSession);
    },
    showShipping() {
      return stripeService.showShipping(paymentSession);
    },
    buy() {
      this.paymentInProgress = true;
      this.canBuy = false;
      return stripeService.requestPayment(paymentSession);
    }
  }
};
</script>

import { StripeAddress, StripeBackendAPI, StripeConfig, StripeCustomerSession, StripePaymentListener, StripePaymentSession, StripeShippingAddressField, StripeShippingMethod } from "nativescript-stripe/standard";
import * as httpModule from "tns-core-modules/http";

// 1) To get started with this demo, first head to https://dashboard.stripe.com/account/apikeys
// and copy your "Test Publishable Key" (it looks like pk_test_abcdef) into the line below.
export const publishableKey = "pk_test_yours";

// 2) Next, optionally, to have this demo save your user's payment details, head to
// https://github.com/stripe/example-ios-backend , click "Deploy to Heroku", and follow
// the instructions (don't worry, it's free). Paste your Heroku URL below
// (it looks like https://blazing-sunrise-1234.herokuapp.com ).
const backendBaseURL = "https://yours.herokuapp.com/";

// 3) Optionally, to enable Apple Pay, follow the instructions at https://stripe.com/docs/apple-pay/apps
// to create an Apple Merchant ID. Paste it below (it looks like merchant.com.yourappname).
const appleMerchantID = "";

export class Listener {

  public component;
  constructor(component) {
    this.component = component;
  }
  onCommunicatingStateChanged(_isCommunicating) {

  }
  onPaymentDataChanged(data) {
    this.component.paymentMethod = data.paymentMethod;
    this.component.shippingInfo = data.shippingInfo;
    this.component.shippingAddress = data.shippingAddress;
  }
  onPaymentSuccess() {
    this.component.successMessage =
      `Congratulations! You bought a "${this.component.stripeItem.name}" for $${this.component.stripeItem.price / 100}.`;

  }
  onUserCancelled() {
  }
  onError(_errorCode, message) {
    this.component.errorMessage = message;
  }
  provideShippingMethods(address) {
    let upsGround = {
      amount: 0,
      label: "UPS Ground",
      detail: "Arrives in 3-5 days",
      identifier: "ups_ground"
    };
    let upsWorldwide = {
      amount: 1099,
      label: "UPS Worldwide Express",
      detail: "Arrives in 1-3 days",
      identifier: "ups_worldwide"
    };
    let fedEx = {
      amount: 599,
      label: "FedEx",
      detail: "Arrives tomorrow",
      identifier: "fedex"
    };
    let methods = {};
    if (!address.country || address.country === "US") {
      methods['isValid'] = true;
      methods['validationError'] = undefined;
      methods['shippingMethods'] = [upsGround, fedEx];
      methods['selectedShippingMethod'] = fedEx;
    }
    else if (address.country === "AQ") {
      methods['isValid'] = false;
      methods['validationError'] = "We can't ship to this country.";
    }
    else {
      fedEx.amount = 2099;
      methods['isValid'] = true;
      methods['validationError'] = undefined;
      methods['shippingMethods'] = [upsWorldwide, fedEx];
      methods['selectedShippingMethod'] = fedEx;
    }
    return methods;
  }
}


export class StripeService implements StripeBackendAPI {
  private customerSession;

  constructor() {
    if (-1 !== publishableKey.indexOf("pk_test_yours")) {
      throw new Error("publishableKey must be changed from placeholder");
    }
    if (-1 !== backendBaseURL.indexOf("https://yours.herokuapp.com/")) {
      throw new Error("backendBaseURL must be changed from placeholder");
    }

    StripeConfig.shared().backendAPI = this;
    StripeConfig.shared().publishableKey = publishableKey;
    StripeConfig.shared().appleMerchantID = appleMerchantID;
    StripeConfig.shared().companyName = "Demo Company";
    StripeConfig.shared().requiredShippingAddressFields = [StripeShippingAddressField.PostalAddress];

    this.customerSession = new StripeCustomerSession();
  }

  private backendURL(pathComponent: string): string {
    if (!backendBaseURL) throw new Error("backendBaseURL must be set");
    if (!backendBaseURL.endsWith("/")) {
      return backendBaseURL + "/" + pathComponent;
    } else {
      return backendBaseURL + pathComponent;
    }
  }

  createCustomerKey(apiVersion: string): Promise<any> {
    let url = this.backendURL("ephemeral_keys");
    return httpModule.request({
      url: url,
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" },
      content: "api_version=" + apiVersion
    }).then(response => {
      if (response.statusCode < 200 || response.statusCode >= 300) {
        throw new Error(response.content.toString());
      }
      return response.content.toJSON();
    });
  }

  completeCharge(stripeID: string, amount: number, shippingMethod: StripeShippingMethod, shippingAddress: StripeAddress): Promise<void> {
    let url = this.backendURL("capture_payment");
    return httpModule.request({
      url: url,
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" },
      content:
        "source=" + stripeID +
        "&amount=" + amount +
        "&" + this.encodeShipping(shippingMethod, shippingAddress)
    }).then(response => {
      if (response.statusCode < 200 || response.statusCode >= 300) {
        throw new Error(response.content.toString());
      }
    });
  }

  private encodeShipping(method: StripeShippingMethod, address: StripeAddress): string {
    function entry(label: string, value: string): string {
      return value ? encodeURI(label) + "=" + encodeURI(value) : "";
    }
    return entry("shipping[carrier]", method.label) +
      entry("&shipping[name]", address.name) +
      entry("&shipping[address][line1]", address.line1) +
      entry("&shipping[address][line2]", address.line2) +
      entry("&shipping[address][city]", address.city) +
      entry("&shipping[address][state]", address.state) +
      entry("&shipping[address][country]", address.country) +
      entry("&shipping[address][postal_code]", address.postalCode) +
      entry("&phone", address.phone) +
      entry("&email", address.email);
  }

  createPaymentSession(page, price, listener?): StripePaymentSession {
    return new StripePaymentSession(page, this.customerSession, price, "usd", listener);
  }

  showPaymentMethods(paymentSession: StripePaymentSession) {
    paymentSession.presentPaymentMethods();
  }

  showShipping(paymentSession: StripePaymentSession) {
    paymentSession.presentShipping();
  }

  requestPayment(paymentSession: StripePaymentSession) {
    paymentSession.requestPayment();
  }
}
<template>
  <Page @loaded="onPageLoaded" class="page">
    <ActionBar class="action-bar">
      <Label class="action-bar-title" text="Home"></Label>
    </ActionBar>

    <StackLayout class="page p-10">
      <GridLayout rows="auto" columns="auto,*">
        <Label row="0" col="0" :text="stripeItem.name" class="h2"></Label>
        <Label row="0" col="1" :text="'$' + stripeItem.price" class="text-right text-muted"></Label>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <GridLayout rows="auto" columns="*,auto" @tap="showPaymentMethods()" class="list-group-item">
        <Label row="0" col="0" text="Payment Type"></Label>
        <StackLayout row="0" col="1" orientation="horizontal">
          <Image width="32" height="20" :src="paymentImage"></Image>
          <Label
            :text="paymentType"
            class="text-right text-muted"
            :visibility="!isLoading ? 'visible' : 'collapse'"
          ></Label>
        </StackLayout>
        <ActivityIndicator
          row="0"
          col="1"
          :busy="isLoading"
          :visibility="isLoading ? 'visible' : 'collapse'"
        ></ActivityIndicator>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <GridLayout rows="auto" columns="auto,*" @tap="showShipping()" class="list-group-item">
        <Label row="0" col="0" text="Shipping Method"></Label>
        <Label row="0" col="1" :text="shippingType" class="text-right text-muted"></Label>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <GridLayout rows="auto" columns="auto,*" class="list-group-item">
        <Label row="0" col="0" text="Total"></Label>
        <Label row="0" col="1" :text="'$ ' + total" class="text-right"></Label>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <Label :text="errorMessage" class="text-danger" textWrap="true"></Label>
      <Button text="Buy" :isEnabled="canBuy" class="btn btn-primary btn-active" @tap="buy()"></Button>
      <ActivityIndicator
        :busy="paymentInProgress"
        :visibility="paymentInProgress ? 'visible' : 'collapse'"
      ></ActivityIndicator>
      <Label :text="successMessage" class="text-primary" textWrap="true"></Label>
      <StackLayout class="hr-light m-10"></StackLayout>
      <Label text="Debug Info"></Label>
      <Label :text="debugInfo" class="body" textWrap="true"></Label>
    </StackLayout>
  </Page>
</template>

<script>
//Change the import of 'stripe.service.ts' to the right path
import { StripeService, Listener } from "~/services/stripe.service.ts";
let stripeService = new StripeService();
var paymentSession = null;
export default {
  data() {
    return {
      stripeItem: {
        id: 0,
        name: "Something to buy",
        price: 1200
      },
      paymentInProgress: false,
      canBuy: true,
      isLoading: false,
      paymentType: "",
      paymentImage: "",
      shippingType: "",
      total: "",
      debugInfo: "",
      successMessage: "",
      errorMessage: ""
    };
  },
  methods: {
    onPageLoaded(args) {
      var comp = this;
      paymentSession = stripeService.createPaymentSession(
        args.object,
        comp.stripeItem.price,
        new Listener(comp)
      );
    },
    showPaymentMethods() {
      return stripeService.showPaymentMethods(paymentSession);
    },
    showShipping() {
      return stripeService.showShipping(paymentSession);
    },
    buy() {
      this.paymentInProgress = true;
      this.canBuy = false;
      return stripeService.requestPayment(paymentSession);
    }
  }
};
</script>

有人吗?

花了好几个小时,我终于明白了。感谢@Manoj的提示

stripe.service.ts:

<template>
  <Page ref="cartPage" class="page">
    <ActionBar class="action-bar">
      <NavigationButton ios:visibility="collapsed" icon="res://menu" @tap="onDrawerButtonTap"></NavigationButton>
      <ActionItem
        icon="res://navigation/menu"
        android:visibility="collapsed"
        @tap="onDrawerButtonTap"
        ios.position="left"
      ></ActionItem>
      <Label class="action-bar-title" text="ShoppingCart"></Label>
    </ActionBar>
    <StackLayout class="page p-10">
              <GridLayout rows="auto" columns="auto,*">
                <Label row="0" col="0" :text="stripeItem.name" class="h2"></Label>
                <Label
                  row="0"
                  col="1"
                  :text="'kr' + stripeItem.price"
                  class="text-right text-muted"
                ></Label>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <GridLayout
                rows="auto"
                columns="*,auto"
                @tap="showPaymentMethods()"
                class="list-group-item"
              >
                <Label row="0" col="0" text="Payment Type"></Label>
                <StackLayout row="0" col="1" orientation="horizontal">
                  <Image width="32" height="20" :src="paymentImage"></Image>
                  <Label
                    :text="paymentType"
                    class="text-right text-muted"
                    :visibility="!isLoading ? 'visible' : 'collapse'"
                  ></Label>
                </StackLayout>
                <ActivityIndicator
                  row="0"
                  col="1"
                  :busy="isLoading"
                  :visibility="isLoading ? 'visible' : 'collapse'"
                ></ActivityIndicator>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <GridLayout rows="auto" columns="auto,*" @tap="showShipping()" class="list-group-item">
                <Label row="0" col="0" text="Shipping Method"></Label>
                <Label row="0" col="1" :text="shippingType" class="text-right text-muted"></Label>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <GridLayout rows="auto" columns="auto,*" class="list-group-item">
                <Label row="0" col="0" text="Total"></Label>
                <Label row="0" col="1" :text="'kr ' + total" class="text-right"></Label>
              </GridLayout>
              <StackLayout class="hr-light m-10"></StackLayout>
              <Label :text="errorMessage" class="text-danger" textWrap="true"></Label>
              <Button text="Buy" :isEnabled="canBuy" class="btn btn-primary btn-active" @tap="buy()"></Button>
              <ActivityIndicator
                :busy="paymentInProgress"
                :visibility="paymentInProgress ? 'visible' : 'collapse'"
              ></ActivityIndicator>
              <Label :text="successMessage" class="text-primary" textWrap="true"></Label>
              <StackLayout class="hr-light m-10"></StackLayout>
              <Label text="Debug Info"></Label>
              <Label :text="debugInfo" class="body" textWrap="true"></Label>
            </StackLayout>
  </Page>
</template>

<script>
import * as utils from "~/shared/utils";
import SelectedPageService from "../shared/selected-page-service";
import { StripeService, Listener } from "~/shared/stripe/stripe.service.ts";

const Page = require("tns-core-modules/ui/page").Page;

let stripeService = new StripeService();
var paymentSession = {};

export default {
  mounted() {
    SelectedPageService.getInstance().updateSelectedPage("ShoppingCart");

    paymentSession = stripeService.createPaymentSession(new Page(), 1213, new Listener(this));
  },
  data() {
    return {
      stripeItem: {
        id: 0,
        name: "Something to buy",
        price: 1200
      },
      paymentInProgress: false,
      canBuy: true,
      isLoading: false,
      paymentType: "",
      paymentImage: "",
      shippingType: "",
      total: "",
      debugInfo: "",
      successMessage: "",
      errorMessage: ""
    };
  },
  methods: {
    onDrawerButtonTap() {
      utils.showDrawer();
    },
    showPaymentMethods() {
      return stripeService.showPaymentMethods(paymentSession);
    },
    showShipping() {
      return stripeService.showShipping(paymentSession);
    },
    buy() {
      this.paymentInProgress = true;
      this.canBuy = false;
      return stripeService.requestPayment(paymentSession);
    }
  }
};
</script>

import { StripeAddress, StripeBackendAPI, StripeConfig, StripeCustomerSession, StripePaymentListener, StripePaymentSession, StripeShippingAddressField, StripeShippingMethod } from "nativescript-stripe/standard";
import * as httpModule from "tns-core-modules/http";

// 1) To get started with this demo, first head to https://dashboard.stripe.com/account/apikeys
// and copy your "Test Publishable Key" (it looks like pk_test_abcdef) into the line below.
export const publishableKey = "pk_test_yours";

// 2) Next, optionally, to have this demo save your user's payment details, head to
// https://github.com/stripe/example-ios-backend , click "Deploy to Heroku", and follow
// the instructions (don't worry, it's free). Paste your Heroku URL below
// (it looks like https://blazing-sunrise-1234.herokuapp.com ).
const backendBaseURL = "https://yours.herokuapp.com/";

// 3) Optionally, to enable Apple Pay, follow the instructions at https://stripe.com/docs/apple-pay/apps
// to create an Apple Merchant ID. Paste it below (it looks like merchant.com.yourappname).
const appleMerchantID = "";

export class Listener {

  public component;
  constructor(component) {
    this.component = component;
  }
  onCommunicatingStateChanged(_isCommunicating) {

  }
  onPaymentDataChanged(data) {
    this.component.paymentMethod = data.paymentMethod;
    this.component.shippingInfo = data.shippingInfo;
    this.component.shippingAddress = data.shippingAddress;
  }
  onPaymentSuccess() {
    this.component.successMessage =
      `Congratulations! You bought a "${this.component.stripeItem.name}" for $${this.component.stripeItem.price / 100}.`;

  }
  onUserCancelled() {
  }
  onError(_errorCode, message) {
    this.component.errorMessage = message;
  }
  provideShippingMethods(address) {
    let upsGround = {
      amount: 0,
      label: "UPS Ground",
      detail: "Arrives in 3-5 days",
      identifier: "ups_ground"
    };
    let upsWorldwide = {
      amount: 1099,
      label: "UPS Worldwide Express",
      detail: "Arrives in 1-3 days",
      identifier: "ups_worldwide"
    };
    let fedEx = {
      amount: 599,
      label: "FedEx",
      detail: "Arrives tomorrow",
      identifier: "fedex"
    };
    let methods = {};
    if (!address.country || address.country === "US") {
      methods['isValid'] = true;
      methods['validationError'] = undefined;
      methods['shippingMethods'] = [upsGround, fedEx];
      methods['selectedShippingMethod'] = fedEx;
    }
    else if (address.country === "AQ") {
      methods['isValid'] = false;
      methods['validationError'] = "We can't ship to this country.";
    }
    else {
      fedEx.amount = 2099;
      methods['isValid'] = true;
      methods['validationError'] = undefined;
      methods['shippingMethods'] = [upsWorldwide, fedEx];
      methods['selectedShippingMethod'] = fedEx;
    }
    return methods;
  }
}


export class StripeService implements StripeBackendAPI {
  private customerSession;

  constructor() {
    if (-1 !== publishableKey.indexOf("pk_test_yours")) {
      throw new Error("publishableKey must be changed from placeholder");
    }
    if (-1 !== backendBaseURL.indexOf("https://yours.herokuapp.com/")) {
      throw new Error("backendBaseURL must be changed from placeholder");
    }

    StripeConfig.shared().backendAPI = this;
    StripeConfig.shared().publishableKey = publishableKey;
    StripeConfig.shared().appleMerchantID = appleMerchantID;
    StripeConfig.shared().companyName = "Demo Company";
    StripeConfig.shared().requiredShippingAddressFields = [StripeShippingAddressField.PostalAddress];

    this.customerSession = new StripeCustomerSession();
  }

  private backendURL(pathComponent: string): string {
    if (!backendBaseURL) throw new Error("backendBaseURL must be set");
    if (!backendBaseURL.endsWith("/")) {
      return backendBaseURL + "/" + pathComponent;
    } else {
      return backendBaseURL + pathComponent;
    }
  }

  createCustomerKey(apiVersion: string): Promise<any> {
    let url = this.backendURL("ephemeral_keys");
    return httpModule.request({
      url: url,
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" },
      content: "api_version=" + apiVersion
    }).then(response => {
      if (response.statusCode < 200 || response.statusCode >= 300) {
        throw new Error(response.content.toString());
      }
      return response.content.toJSON();
    });
  }

  completeCharge(stripeID: string, amount: number, shippingMethod: StripeShippingMethod, shippingAddress: StripeAddress): Promise<void> {
    let url = this.backendURL("capture_payment");
    return httpModule.request({
      url: url,
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" },
      content:
        "source=" + stripeID +
        "&amount=" + amount +
        "&" + this.encodeShipping(shippingMethod, shippingAddress)
    }).then(response => {
      if (response.statusCode < 200 || response.statusCode >= 300) {
        throw new Error(response.content.toString());
      }
    });
  }

  private encodeShipping(method: StripeShippingMethod, address: StripeAddress): string {
    function entry(label: string, value: string): string {
      return value ? encodeURI(label) + "=" + encodeURI(value) : "";
    }
    return entry("shipping[carrier]", method.label) +
      entry("&shipping[name]", address.name) +
      entry("&shipping[address][line1]", address.line1) +
      entry("&shipping[address][line2]", address.line2) +
      entry("&shipping[address][city]", address.city) +
      entry("&shipping[address][state]", address.state) +
      entry("&shipping[address][country]", address.country) +
      entry("&shipping[address][postal_code]", address.postalCode) +
      entry("&phone", address.phone) +
      entry("&email", address.email);
  }

  createPaymentSession(page, price, listener?): StripePaymentSession {
    return new StripePaymentSession(page, this.customerSession, price, "usd", listener);
  }

  showPaymentMethods(paymentSession: StripePaymentSession) {
    paymentSession.presentPaymentMethods();
  }

  showShipping(paymentSession: StripePaymentSession) {
    paymentSession.presentShipping();
  }

  requestPayment(paymentSession: StripePaymentSession) {
    paymentSession.requestPayment();
  }
}
<template>
  <Page @loaded="onPageLoaded" class="page">
    <ActionBar class="action-bar">
      <Label class="action-bar-title" text="Home"></Label>
    </ActionBar>

    <StackLayout class="page p-10">
      <GridLayout rows="auto" columns="auto,*">
        <Label row="0" col="0" :text="stripeItem.name" class="h2"></Label>
        <Label row="0" col="1" :text="'$' + stripeItem.price" class="text-right text-muted"></Label>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <GridLayout rows="auto" columns="*,auto" @tap="showPaymentMethods()" class="list-group-item">
        <Label row="0" col="0" text="Payment Type"></Label>
        <StackLayout row="0" col="1" orientation="horizontal">
          <Image width="32" height="20" :src="paymentImage"></Image>
          <Label
            :text="paymentType"
            class="text-right text-muted"
            :visibility="!isLoading ? 'visible' : 'collapse'"
          ></Label>
        </StackLayout>
        <ActivityIndicator
          row="0"
          col="1"
          :busy="isLoading"
          :visibility="isLoading ? 'visible' : 'collapse'"
        ></ActivityIndicator>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <GridLayout rows="auto" columns="auto,*" @tap="showShipping()" class="list-group-item">
        <Label row="0" col="0" text="Shipping Method"></Label>
        <Label row="0" col="1" :text="shippingType" class="text-right text-muted"></Label>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <GridLayout rows="auto" columns="auto,*" class="list-group-item">
        <Label row="0" col="0" text="Total"></Label>
        <Label row="0" col="1" :text="'$ ' + total" class="text-right"></Label>
      </GridLayout>
      <StackLayout class="hr-light m-10"></StackLayout>
      <Label :text="errorMessage" class="text-danger" textWrap="true"></Label>
      <Button text="Buy" :isEnabled="canBuy" class="btn btn-primary btn-active" @tap="buy()"></Button>
      <ActivityIndicator
        :busy="paymentInProgress"
        :visibility="paymentInProgress ? 'visible' : 'collapse'"
      ></ActivityIndicator>
      <Label :text="successMessage" class="text-primary" textWrap="true"></Label>
      <StackLayout class="hr-light m-10"></StackLayout>
      <Label text="Debug Info"></Label>
      <Label :text="debugInfo" class="body" textWrap="true"></Label>
    </StackLayout>
  </Page>
</template>

<script>
//Change the import of 'stripe.service.ts' to the right path
import { StripeService, Listener } from "~/services/stripe.service.ts";
let stripeService = new StripeService();
var paymentSession = null;
export default {
  data() {
    return {
      stripeItem: {
        id: 0,
        name: "Something to buy",
        price: 1200
      },
      paymentInProgress: false,
      canBuy: true,
      isLoading: false,
      paymentType: "",
      paymentImage: "",
      shippingType: "",
      total: "",
      debugInfo: "",
      successMessage: "",
      errorMessage: ""
    };
  },
  methods: {
    onPageLoaded(args) {
      var comp = this;
      paymentSession = stripeService.createPaymentSession(
        args.object,
        comp.stripeItem.price,
        new Listener(comp)
      );
    },
    showPaymentMethods() {
      return stripeService.showPaymentMethods(paymentSession);
    },
    showShipping() {
      return stripeService.showShipping(paymentSession);
    },
    buy() {
      this.paymentInProgress = true;
      this.canBuy = false;
      return stripeService.requestPayment(paymentSession);
    }
  }
};
</script>
从“nativescript stripe/standard”导入{StripeAddress、StripeBackendAPI、StripeConfig、StripeCustomerSession、StripePaymentListener、StripePaymentSession、StripeShippingAddressField、StripeShippingMethod};
从“tns核心模块/http”导入*作为httpModule;
//1)要开始此演示,请首先访问https://dashboard.stripe.com/account/apikeys
//并将您的“测试可发布密钥”(看起来像pk_Test_abcdef)复制到下面的行中。
export const publishableKey=“pk\u test\u yours”;
//2)下一步(可选)要让此演示保存用户的付款详细信息,请访问
// https://github.com/stripe/example-ios-backend ,单击“部署到Heroku”,然后按照
//说明书(别担心,它是免费的)。将你的Heroku URL粘贴到下面
//(看起来像https://blazing-sunrise-1234.herokuapp.com ).
const backendBaseURL=”https://yours.herokuapp.com/";
//3)或者,要启用Apple Pay,请按照https://stripe.com/docs/apple-pay/apps
//要创建苹果商户ID,请将其粘贴到下面(看起来像Merchant.com.yourappname)。
const appleMerchantID=“”;
导出类侦听器{
公共部分;
构造函数(组件){
这个组件=组件;
}
OnCommunicationsState已更改(正在通信){
}
onPaymentDataChanged(数据){
this.component.paymentMethod=data.paymentMethod;
this.component.shippingInfo=data.shippingInfo;
this.component.shippingAddress=data.shippingAddress;
}
onPaymentSuccess(){
this.component.successage=
`祝贺你!你用$${this.component.stripeItem.price/100}买了一个“${this.component.stripeItem.name}”;
}
联塞特派团(){
}
onError(错误代码、消息){
this.component.errorMessage=消息;
}
provideShippingMethods(地址){
让地面上升={
金额:0,
标签:“UPS地面”,
详情:“3-5天内到达”,
标识符:“ups\U接地”
};
让我们来看一看{
金额:1099,
标签:“UPS环球快递”,
详情:“1-3天内到达”,
标识符:“ups\U全球”
};
让联邦快递={
金额:599,
标签:“联邦快递”,
细节:“明天到达”,
标识符:“联邦快递”
};
让方法={};
如果(!address.country | address.country==“US”){
方法['isValid']=true;
方法['validationError']=未定义;
方法['shippingMethods']=[Upground,fedEx];
方法['selectedShippingMethod']=fedEx;
}
否则如果(address.country==“AQ”){
方法['isValid']=false;
方法['validationError']=“我们无法运送到这个国家。”;
}
否则{
联邦快递金额=2099;
方法['isValid']=true;
方法['validationError']=未定义;
方法['shippingMethods']=[upsWorldwide,fedEx];
方法['selectedShippingMethod']=fedEx;
}
返回方法;
}
}
导出类StripeService实现StripeBackendAPI{
私人客户服务;
构造函数(){
如果(-1!==publishableKey.indexOf(“pk\U测试您的”)){
抛出新错误(“publishableKey必须从占位符更改”);
}
如果(-1!==backendBaseURL.indexOf(“https://yours.herokuapp.com/")) {
抛出新错误(“必须从占位符更改backendBaseURL”);
}
StripeConfig.shared().backendAPI=this;
StripeConfig.shared().publishableKey=publishableKey;
StripeConfig.shared().appleMerchantID=appleMerchantID;
StripeConfig.shared().companyName=“演示公司”;
StripeConfig.shared().requiredShippingAddressFields=[StripeShippingAddressField.PostLaddress];
this.customerSession=新的StripeCustomerSession();
}
专用后端URL(路径组件:字符串):字符串{
如果(!backendBaseURL)抛出新错误(“必须设置backendBaseURL”);
如果(!backendBaseURL.endsWith(“/”)){
返回backendBaseURL+“/”+pathComponent;
}否则{
返回backendBaseURL+pathComponent;
}
}
createCustomerKey(apiVersion:string):承诺{
设url=this.backendURL(“短暂的_键”);
返回httpModule.request({
url:url,
方法:“张贴”,
标题:{“内容类型”:“application/x-www-form-urlencoded;charset=utf-8”},