Skip to content

Commit

Permalink
Update demo-angular Intents.
Browse files Browse the repository at this point in the history
Work with latest Stripe example-backend.
  - (No longer works with older version)
Convert to Promises to make code more clear.
  • Loading branch information
RobertGardner committed Apr 28, 2020
1 parent 49b9f9a commit 99affa1
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 66 deletions.
171 changes: 110 additions & 61 deletions demo-angular/app/demo/intent.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { ChangeDetectorRef, Component, ViewContainerRef, Input } from "@angular/core";
import { ChangeDetectorRef, Component, ViewContainerRef } from "@angular/core";
import { ModalDialogService } from "nativescript-angular/modal-dialog";
import { CreditCardView, PaymentMethod, Stripe, Token, StripePaymentIntentParams, StripePaymentIntent } from "nativescript-stripe";
import { isAndroid } from "tns-core-modules/platform";
import { publishableKey, StripeService } from "./stripe.service";
import { Card, CreditCardView, PaymentMethod, Stripe, StripePaymentIntentParams } from "nativescript-stripe";
import { alert } from "tns-core-modules/ui/dialogs";

import { ItentModalComponent } from "./intent-modal.component";
import { publishableKey, StripeService } from "./stripe.service";

@Component({
selector: "stp-intent",
Expand Down Expand Up @@ -43,88 +41,139 @@ export class IntentComponent {
}

registerCard(cardView: CreditCardView) {
console.log("registerCard");
this._setStatus("Create Setup Intent...");
this.stripeService.createSetupIntent().then((intent) => {

this._setStatus("Create Payment Method...");
this.stripe.createPaymentMethod(cardView.card, (error, pm) => {
if (error) return this._displayError(error);
this._setStatus("Confirm Setup Intent...");
this.stripe.confirmSetupIntent(pm.id, intent.secret, (error, setupIntent) => {
if (error) this._displayError(error);
this._setStatus(`Setup Intent Status => ${setupIntent.status}`);
});
});
});
this.stripeService.createSetupIntent()
.then(intent => this._createPaymentMethod(cardView.card)
.then(pm => this._confirmSetupIntent(pm.id, intent.secret))
.then(setupIntent => this._setStatus(`Setup Intent Status => ${setupIntent.status}`)))
.catch(err => this._displayError(err, "registerCard"));
}

// Authenticate and charge on the UI
// https://stripe.com/docs/payments/payment-intents/ios#automatic-confirmation-ios
// https://stripe.com/docs/payments/payment-intents/ios
automaticConfirmPayment(cardView: CreditCardView) {
this._setStatus("Create Payment Method...");
this.stripe.createPaymentMethod(cardView.card, (error, pm) => {
if (error) return this._displayError(error);
this._createPaymentIntent().then(p => {
const piParams = new StripePaymentIntentParams();
piParams.paymentMethodId = pm.id;
piParams.clientSecret = p.secret;
this._confirmPaymentIntent(piParams);
});
});
console.log("automaticConfirmPayment");
this._createPaymentMethod(cardView.card)
.then(pm => this._createPaymentIntent()
.then(pi => this._confirmPaymentIntent(pm.id, pi.secret))
.then(pi => this._setStatus(`Payment Status: ${pi.status}`)))
.catch(err => this._displayError(err, "automaticConfirmPayment"));
}

// Authenticate on the UI only, confirm charge on back-end
// https://stripe.com/docs/payments/payment-intents/ios#handle-authentication-manual
// https://stripe.com/docs/payments/payment-intents/ios-manual
manualConfirmPayment(cardView: CreditCardView) {
this._setStatus("Create Payment Method...");
this.stripe.createPaymentMethod(cardView.card, (error, pm) => {
if (error) return this._displayError(error);

this._setStatus("Create Payment Intent...");
this.stripeService.capturePayment(pm.id, this._item.price).then(({ secret }) => {

this._setStatus("Authenticate Payment Intent...");
this.stripe.authenticatePaymentIntent(secret, null, (error, pintent) => {
if (error) return this._displayError(error);
if (pintent.requiresConfirmation) {
this._setStatus("Confirm Payment Intent...");
this.stripeService.confirmPaymentIntent(pintent.id).then(response => {
this._setStatus(`Payment Intent Processed: ${JSON.stringify(response)}`);
});
} else {
// Not ready to be processed by backend
this._setStatus(`Payment Status: ${pintent.status}`);
}
});
});
});
console.log("manualConfirmPayment");
this._createPaymentMethod(cardView.card)
.then(pm => this._createManualPaymentIntent(pm.id))
.then(pi => {
if (pi.requires_action) return this._authenticatePaymentIntent(pi.secret);
return pi;
})
.then(pi => {
if (pi.requiresConfirmation) {
return this._confirmManualPaymentIntent(pi.id)
.then(response => `Payment Intent Processed: ${JSON.stringify(response)}`);
} else if (!pi.status) {
pi.status = pi.success ? "success" : "failed";
}
return `Payment Status: ${pi.status}`;
})
.then(status => this._setStatus(status))
.catch(err => this._displayError(err, "manualConfirmPayment"));
}

/*
* Private
* Private. Convert callback-based calls to Stripe with Promises.
*/

private _createPaymentMethod(card: Card): Promise<PaymentMethod> {
this._setStatus(`Create Payment Method (${card.brand} ${card.last4})...`);
return new Promise((resolve, reject) => {
this.stripe.createPaymentMethod(card, (error, pm) => {
if (error) return reject(error);
console.log("Stripe.createPaymentMethod response:", pm.id);
resolve(pm);
});
});
}

private _createPaymentIntent(): Promise<any> {
this._setStatus("Create Payment Intent...");
return this.stripeService.createPaymentIntent(this._item.price, this._item.currency);
return this.stripeService.createPaymentIntent(this._item.price, this._item.currency)
.then(response => {
console.log('StripeService.createPaymentIntent response:', response);
return response;
});
}

private _confirmPaymentIntent(piParams) {
this._setStatus("Confirm Payment Intent...");
this.stripe.confirmPaymentIntent(piParams, (error, pintent) => {
if (error) return this._displayError(error);
this._setStatus(`Payment Status: ${pintent.status}`);
private _createManualPaymentIntent(pmId: string): Promise<any> {
this._setStatus(`Create Manual Payment Intent (${pmId})...`);
return this.stripeService.capturePayment(pmId, this._item.price)
.then(response => {
console.log('StripeService.capturePayment response:', response);
return response;
});
}

private _confirmManualPaymentIntent(id: string): Promise<any> {
this._setStatus("Confirm Manual Payment Intent...");
return this.stripeService.confirmPaymentIntent(id)
.then(response => {
console.log('StripeService.confirmPaymentIntent response:', response);
return response;
});
}

private _confirmSetupIntent(id: string, secret: string): Promise<any> {
this._setStatus(`Confirm Setup Intent (${id}, ${secret})...`);
return new Promise((resolve, reject) => {
this.stripe.confirmSetupIntent(id, secret, (error, setupIntent) => {
if (error) return reject(error);
console.log("Stripe.confirmSetupIntent response:", setupIntent.id, setupIntent.status);
resolve(setupIntent);
});
});
}

private _confirmPaymentIntent(pmId: string, secret: string): Promise<any> {
this._setStatus(`Confirm Payment Intent (${pmId}, ${secret})...`);
const piParams = new StripePaymentIntentParams();
piParams.paymentMethodId = pmId;
piParams.clientSecret = secret;
return new Promise((resolve, reject) => {
this.stripe.confirmPaymentIntent(piParams, (error, pintent) => {
if (error) return reject(error);
console.log("Stripe.confirmPaymentIntent response:", pintent.id, pintent.status);
resolve(pintent);
});
});
}

private _authenticatePaymentIntent(secret: string): Promise<any> {
this._setStatus(`Authenticate Payment Intent (${secret})...`);
return new Promise((resolve, reject) => {
this.stripe.authenticatePaymentIntent(secret, null, (error, pintent) => {
if (error) return reject(error);
console.log("Stripe.authenticatePaymentIntent response:", JSON.stringify(pintent));
resolve(pintent);
});
});
}

private _setStatus(message) {
private _setStatus(message: string) {
console.log(message);
this.status = message;
this.changeDetectionRef.detectChanges();
}

private _displayError(message) {
private _displayError(error: Error, operation: string) {
const msg = "Error during " + operation;
console.log(msg, error.message, error.stack);
alert({
message,
title: msg,
message: error.message,
okButtonText: "OK"
}).then(() => this._setStatus(null));
}
Expand Down
10 changes: 5 additions & 5 deletions demo-angular/app/demo/stripe.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export class StripeService implements StripeBackendAPI {
// PaymentIntent
createPaymentIntent(amount: number, currency: string = 'usd'): Promise<any> {
const content = `amount=${amount}&currency=${currency}`;
return this._postRequest("create_intent", content).then(response => response.content.toJSON());
return this._postRequest("create_payment_intent", content).then(response => response.content.toJSON());
}

createCustomerKey(apiVersion: string): Promise<any> {
Expand All @@ -55,14 +55,14 @@ export class StripeService implements StripeBackendAPI {
}

capturePayment(stripeID: string, amount: number, shippingMethod?: StripeShippingMethod, shippingAddress?: StripeAddress): Promise<any> {
let content = `payment_method=${stripeID}&amount=${amount}`;
let content = `payment_method_id=${stripeID}&amount=${amount}`;
if (shippingMethod && shippingAddress) content += `&${this._encodeShipping(shippingMethod, shippingAddress)}`;
return this._postRequest("capture_payment", content).then(response => response.content.toJSON());
return this._postRequest("confirm_payment_intent", content).then(response => response.content.toJSON());
}

confirmPaymentIntent(paymentIntentID: string): Promise<any> {
const content = `payment_intent_id=${paymentIntentID}`;
return this._postRequest("confirm_payment", content).then(response => response.content.toJSON());
return this._postRequest("confirm_payment_intent", content).then(response => response.content.toJSON());
}

createPaymentSession(page: Page, price: number, listener?: StripePaymentListener): StripePaymentSession {
Expand Down Expand Up @@ -94,7 +94,7 @@ export class StripeService implements StripeBackendAPI {
content
}).then(response => {
if (response.statusCode < 200 || response.statusCode >= 300) {
throw new Error(response.content.toString());
throw new Error(`Status: ${response.statusCode}; ${response.content.toString()}.`);
}
return response;
});
Expand Down

0 comments on commit 99affa1

Please sign in to comment.