sepa_debit payemnt method with stripe subscriptopn doesn't work - react-native

I'm using Stripe with react-native and I want to integrate PaymentIntent with Subscription as described in this tutorial
the issue is I can't show the SEPA as a valid payment option at the front-end.
Stripe mentioned in their subscription API docs that you can pass the payment_method_types as you do in payment_intent. however, it seems like it doesn't work!
let me explain with examples
first scenario using the regular payment_intent
const paymentIntent = await stripe.paymentIntents.create({
amount: 1099,
currency: 'EUR',
customer: customer.id,
payment_method_types: ["card", "sepa_debit"]
});
return res.json({
// #ts-ignore
paymentIntent: paymentIntent.client_secret,
ephemeralKey: ephemeralKey.secret,
customer: customer.id,
});
and the result would be like as you can see the SEPA option is showing
second scenario when I'm using the subscription
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [{
price: "price_1JwZ4tJyYehXW8ayueOKGDUM",
}],
payment_settings: {
payment_method_types: ["card", "sepa_debit"]
},
payment_behavior: 'default_incomplete',
expand: ['latest_invoice.payment_intent'],
});
return res.json({
// #ts-ignore
paymentIntent: subscription.latest_invoice.payment_intent.client_secret,
ephemeralKey: ephemeralKey.secret,
customer: customer.id,
});
the result would be like (no SEPA option)
any idea why sepa_debit working with payment_intent and not with subscription?

The Payment Intent that is generated during Subscription creation automatically sets setup_future_usage: off_session to ensure that the saved Payment Method can be used for off-sessions recurring payments in the future.
Looking at the code for Stripe's React Native SDK it looks like it relies on logic found in the Android and iOS to determine when to show sepa_debit as an option in the Payment Sheet. Both these SDKs do not currently support sepa_debit for a Payment Intent with setup_future_usage set, which explains why you're not seeing it show up as an option for your Subscription Payment Intent. You can see the code I referenced here:
Android
iOS

Related

react-native-iap I have problem with successfully make a subscription payment

Have anyone successfully implemented in app subscriptions with react-native-iap in an app.
I have tried to implement it but still very unstable. Can't rely that the subscription payments work every time. Sometimes the pay dialog won't show, sometimes it won't continue, and so on. Its a problem on both android and iOS.
Short explanation on how I have implemented it:
When clicked on pay button after the user has selected the plan, for ex. monthly.
await requestSubscription({
sku: subscription.productId,
...(offerToken && { subscriptionOffers: [{sku: subscription.productId, offerToken}]}),
})
Then I have to listeners, currentPurchaseError and currentPurchase that is returned as a hook from the rniap library.
React.useEffect(() => {
const onError = async () => {
// Do something on error from rniap.
}
if (currentPurchaseError) {
onError()
}
}, [currentPurchaseError])
And
React.useEffect(() => {
const checkCurrentPurchase = async () => {
// Do something, this should trigger when a purchase is successful.
}
if (currentPurchase) {
checkCurrentPurchase()
}
}, [currentPurchase, finishTransaction])
My receipt validation is happening on our own backend and its worth mentioning that everything there is working.
As I asked, has anyone implemented this successfully. If so, how?
Or is it worth thinking of changing to like revenue cat?
rniap's documentation and example code is really small and right now I need some help.
/Alexander
I have tried to get a successful payment within iOS sandbox but with no luck.

React-native Stripe Payment Sheet with Subscription

I'm using stripe-react-native to handle payment, and I'm able to handle one-time payment via payment-sheet using PaymentIntent flow.
Now I'm stuck with creating subscription using the same payment sheet flow, has anyone tried this before? Or an advise how to use PaymentIntent in subscription?
You need to expand the subscription object with payment intent.
const subscription = await stripe.subscriptions.create({
...subscriptionSettings
expand: ['latest_invoice.payment_intent']
});
You can then access it using:
const paymentIntent = subscription.latest_invoice.payment_intent
const clientSecret = subscription.latest_invoice.payment_intent.client_secret

CRYPTOGRAM_3DS – Why doesn't it work as the only option?

I'm trying to add Google Pay support to a website where we already have it working for a native app. The in-app implementation does not allow PAN_ONLY cards (due to high chargebacks), only CRYPTOGRAM_3DS. This works just fine.
When I configure the website to only allow CRYPTOGRAM_3DS, I can never get paymentsClient.isReadyToPay() to return true. I've tried different Android devices which are able to make in-app payments with no success. To be clear: If I allow PAN_ONLY then Google Pay works as expected and I can obtain tokens.
How can I troubleshoot the reason why this is happening? Does it work for anyone else if you remove PAN_ONLY from the setup config?
thanks!
CRYPTOGRAM_3DS refers to tokenized cards. That is, cards that have been added and stored on you Android device. These are the same cards that you can use to pay in-store (not in-app) with Tap and Pay.
If you are using CRYPTOGRAM_3DS only, this means that it will currently only work on a Android device where a user has saved a tokenized card.
I've put the following example together to demonstrate (make sure you test on a Android device with appropriate cards): https://jsfiddle.net/w5ptorbd/
<script src="https://unpkg.com/#google-pay/button-element#2.x/dist/index.umd.js"></script>
<google-pay-button environment="TEST"></google-pay-button>
const button = document.querySelector('google-pay-button');
button.paymentRequest = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [
{
type: 'CARD',
parameters: {
allowedAuthMethods: ['CRYPTOGRAM_3DS'],
allowedCardNetworks: ['MASTERCARD', 'VISA'],
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'example',
gatewayMerchantId: 'exampleGatewayMerchantId',
},
},
},
],
merchantInfo: {
merchantId: '12345678901234567890',
merchantName: 'Demo Merchant',
},
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPriceLabel: 'Total',
totalPrice: '100.00',
currencyCode: 'USD',
countryCode: 'US',
},
};
button.addEventListener('loadpaymentdata', event => {
console.log('load payment data', event.detail);
});
button.addEventListener('readytopaychange', event => {
console.log('ready to pay change', event.detail);
});

What is razorpay orders api and how to integrate it with react native?

I am trying to implement a payment module in my react native app and trying to use Razorpay. As per documentation, there are two main things, the checkout, and the orders API. What is the difference between the two? What is exactly orders API and how is it to be used in react native? They have given many options in the docs to integrate the orders API like java, ruby, etc but nothing for react native. So any help would be appreciated. Thank you.
The Razorpay has integrated the checkout function for react-native, which means it will lead to the calling of payment API, what this does is accepts payment from any user directly transferring the money without any details. With orders API, Razorpay enables you to create Orders that can be linked to payments. That means So that whatever payment arrives in your wallet is described with what has the payment related to. For example, suppose you have to show a product you wish to sell.
So first, you will have to create an order by calling orders API on your server-side, i.e. Node.JS or something else with request parameters like the amount, self-generated receipt number, and optional notes on who the user is. then after receiving the order_id, you will pass onto the mobile application and start the checkout functionality provided by react-native-razorpay.
Here is the example on how I used the react-native-razorpay.
On server-side - node.js:
const Razorpay = require("razorpay");
//...
let rzp = new Razorpay({
key_id: "", // your `KEY_ID`
key_secret: "" // your `KEY_SECRET`
});
//Inside Create Order Function
rzp.orders
.create({
amount: price * 100,
currency: "INR",
receipt: "", // Add receipt string
payment_capture: 1, // auto capture payment config
notes: { username, planId: id }
// custom notes, you can use this in received response as key-value pair
})
.then(data => { // created order response
let sendToApplicationResponse = { // Creating the response send to mobile app
username,
orderId: data.id,
receipt: data.receipt
};
return sendToApplicationResponse;
})
On react-native application-side:
import RazorpayCheckout from 'react-native-razorpay';
//.....
onPress={async () => {
//Call my server to create an Order
// passing userId and price and plan selected as request parameters
// and waiting for the response
const response = await .....
// You can add parameters given in payment API
var options = {
currency: 'INR',
key: '', // add your razorpay key here
amount: price * 100,
order_id: response.data.orderId, // using the orderId which
prefill: { // add prefill details if you want
contact: "",
name: "",
},
payment_capture: 1,
};
// Call the razorpay checkout
RazorpayCheckout.open(options)
.then(data => {
console.log('RazorpayCheckout', data);
Alert.alert('Payment Successful!');
})
.catch(error => {
Alert.alert('Something went wrong!');
// Alert.alert(`Error: ${error.code} | ${error.description}`);
});
}}

Payment token becomes undefined after the Apple Pay process

I am developing an Apple Pay with react-native. I configured everything and I used react-native-payment component. Here is my code:
onPressApplePay=()=>{
console.log("1- start Apple Pay");
if (!DataManager.getInstance().isConnected()) {
this.myAlert(I18n.t("NoInternetConnectionState"));
return;
}
const DETAILS = {
id: 'basic-example',
displayItems: [
{
label: 'items',
amount: { currency: 'EUR', value: '2' },
},
],
total: {
label: 'MyApp',
amount: { currency: 'EUR', value: '2' },
},
};
const METHOD_DATA = [{
supportedMethods: ['apple-pay'],
data: {
merchantIdentifier: 'merchant.com.myapp',
supportedNetworks: [ 'mastercard', 'visa'],
countryCode: 'IT',
currencyCode: 'EUR'
}
}];
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS);
console.log("2- paymentRequest.show", paymentRequest);
paymentRequest.show()
.then((paymentResponse) => {
const { paymentToken } = paymentResponse.details; // On Android, you need to invoke the `getPaymentToken` method to receive the `paymentToken`.
paymentRequest.canMakePayments()
.then(canMakePayments => {
console.log("canMakePayments", canMakePayments);
console.log("paymentToken", paymentToken);
// Show fallback payment method
});
})
.catch((err) => {
console.log("4- err", err);
console.log("5- paymentRequest", err);
//alert("The apple pay cancel");
// The API threw an error or the user closed the UI
});
The problem is that as I try to execute the Apple Pay, it says that the 'Payment is not completed' and the token becomes undefined. Can you please ket me know where the problem might be hiden.
I should mention that I tried this code on a real device using both real card and sandBox and in all cases it was failed. Thanks in advance.
This component is also working with stripe and Braintree. The problem was that I needed to add a gateway and a public key which in my case it provided from stripe.
const METHOD_DATA = [{
supportedMethods: ['apple-pay'],
data: {
merchantIdentifier: 'merchant.yyyy.xxxx',
supportedNetworks: [ 'mastercard'],
countryCode: 'IT',
currencyCode: 'EUR',
paymentMethodTokenizationParameters: {
parameters: {
gateway: 'stripe',
'stripe:publishableKey': 'pk_test_XXXXXXX',
'stripe:version': '5.0.0' // Only required on Android
}
}
}
}];
Then I installed the following add on:
yarn add react-native-payments-addon-stripe
yarn add react-native-payments-cli
yarn react-native-payments-cli -- link stripe
(You also need the Carthage update there to make them work)
Then I made an account in stripe.com and use the publish key of that and finally it works!!
Also I have added paymentResponse.complete('success'); to show the successful payment at the end. Without that it sucks in a loop of waiting and finally shows 'Payment is not complete'.
Now I have a successful message with a nice token!
I should mention that in the case that you don't use stripe or Braintree, you will not see any token and it will be always undefined. It is natural, so don't worry. You just need to pass paymentResponse.details as a JSON to your bank provider and it will work. Because in that case the transactionid will be important which you have it.
After that, you go through these steps of installing from this link . You also need to do these steps regarded to certificates for Apple Pay:
1- First on your App ID in your apple developer account you should enable the Apple Pay with the merchant ID.
2- Then you need to ask from your bank for a certificate on you merchant which is a file that looks like this:
XXXXX.certSigningRequest.txt
3- Then select your app ID and go to Apple Pay section which was enabled in step one and upload the certificate there.
Done! Your Apple Pay will work.
The mention saved me! I didn't realize that it was normal the token would be nil if you aren't using Stripe/Braintree!