Reputation: 105
I'm following this guide - https://stripe.com/docs/payments/accept-a-payment?platform=react-native&ui=payment-sheet-custom
I'm trying to tweak the guide so that I can use the pre-built UI but I want to charge my customers later.
Annoyingly after presentPaymentSheet()
is called the card is charged instantly however I want to charge the customer later after I've done some checking in the backend which will take a few hours/days.
Any advice would be greatly appreciated :)
import Stripe from 'stripe';
import express from "express";
const app = express()
import bodyParser from "body-parser";
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
const stripe = new Stripe('[API_KEY]',{
apiVersion: '2020-08-27',
});
const port = 3000
var customer:Stripe.Response<Stripe.Customer>;
(async()=>{
const _customer = await stripe.customers.retrieve("cus_KI8Y2B5gIU9nZI");
if(_customer.deleted == true) throw new Error("Customer is deleted!");
customer = _customer;
})();
app.post('/configure-paymentsheet', async (req, res) => {
const ephemeralKey = await stripe.ephemeralKeys.create(
{customer: customer.id},
{apiVersion: '2020-08-27'}
);
const paymentIntent = await stripe.paymentIntents.create({
amount: 299,
currency: 'gbp',
customer: customer.id,
confirm:false,
off_session:true
});
res.send({
ephemeralKey: ephemeralKey.secret,
paymentIntent: paymentIntent.client_secret,
customer: customer.id
})
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
import React from 'react';
import { View, Button } from 'react-native';
import axios from "axios";
import { StripeProvider, initPaymentSheet, presentPaymentSheet } from '@stripe/stripe-react-native';
export default class App extends React.Component{
componentDidMount = ()=>{
this.configurePaymentsheet()
}
private configurePaymentsheet = async()=>{
const {data} = await axios.post("http://192.168.1.199:3000/configure-paymentsheet");
const { error } = await initPaymentSheet({
customerId: data.customer,
customerEphemeralKeySecret: data.ephemeralKey,
paymentIntentClientSecret: data.paymentIntent,
});
if(error){
throw error;
}
}
private openPaymentsheet = async()=>{
const { error, paymentOption } = await presentPaymentSheet();
if (error) {
throw error
}
}
render(){
return(
<StripeProvider
publishableKey="[API_KEY]"
urlScheme="localhost" // required for 3D Secure and bank redirects
>
<View>
<Button title="Open payment" onPress={this.openPaymentsheet}/>
</View>
</StripeProvider>
)
}
}
Upvotes: 0
Views: 497
Reputation: 1354
If your checks normally take less than 7 days you can place a hold on the card and capture the funds later after you have done your checks[1]. If you determine that you should not charge the customer, you can cancel the PaymentIntent that you used to hold the funds.
If your checks will take longer than 7 days, you will want to save the payment method and charge it later. Stripe has a “Set up future payments” tutorial for that flow[2], demonstrating how to collect the card details, save them, and charge the card after you have done your checks. Make sure to keep in mind the sections about off-session parameters and starting a recovery flow to give yourself the best chance at success when charging the card later and to allow your customers to respond if further action is needed from them.
[1]https://stripe.com/docs/payments/capture-later
[2]https://stripe.com/docs/payments/save-and-reuse?platform=react-native
Upvotes: 1