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”},