Flutter stripe_payment Native pay not charged(Apple Pay and Google Pay)
Before look into the code, please make sure you have finished the following steps: 0. stripe_payment is added.
- Merchant Id has been created.
- Apple Pay has been enabled in Xcode.
- Stripe "Standard Key" and "Restricted Key" have been generated.
- standard key contains publishable key and secret key
- publishable key uses in Flutter project.
- restricted key uses in Server side.
What i have been done for the native payment:
- calls paymentRequestWithNativePay() to get token.
- charges with own implemented charge method(on Server side, makes sure you use the restricted key and it has charge write permission).
- calls paymentRequestWithNativePay()
void handleNativePayment(BuildContext context, String amountInStr) async {
// I used environment configurations for ANDROID_PAY_MODE, use "test" in test mode
// and uses "production" in production mode
StripePayment.setOptions(StripeOptions(
publishableKey: _publishableKey,
merchantId: _merchantId,
androidPayMode: EnvironmentConfig.ANDROID_PAY_MODE,
));
// this is my service class talks to server side API
PaymentService paymentService = Provider.of<PaymentService>(
context,
listen: false,
);
Token token = await StripePayment.paymentRequestWithNativePay(
androidPayOptions: AndroidPayPaymentRequest(
totalPrice: amountInStr,
currencyCode: _currencyCode,
),
applePayOptions: ApplePayPaymentOptions(
countryCode: _countryCode,
currencyCode: _currencyCode,
items: [
ApplePayItem(
type: 'final',
label: paymentLabel,
amount: amountInStr,
)
],
),
);
// converts amount from string to int, and it is in cents
dynamic chargeResult = await paymentService.charge({
"token": token.tokenId,
"amount": double.parse(amountInStr) * 100,
"currency": _currencyCode,
});
if (chargeResult is ChargeResult) {
_buildSnackBar(context, "Payment success", Colors.green);
} else {
_buildSnackBar(context, "Payment fail", Colors.red);
}
await StripePayment.completeNativePayRequest();
}
_buildSnackBar(BuildContext context, String content, Color color) {
final snackBar = SnackBar(
content: Text(content),
backgroundColor: color,
);
Scaffold.of(context).showSnackBar(snackBar);
}
Here's the PaymentService in Flutter. You need implement the server side charge API call with the Stripe restricted key.
class PaymentService {
var logger = Logger(printer: PrettyPrinter());
Future<dynamic> charge(Map<String, dynamic> data) async {
Map<String, dynamic> charge = {
"source": data["token"],
"amount": data["amount"],
"currency": data["currency"],
};
final response = await DioHttp.post('/stripe/payment/charge', charge);
if (response.containsKey("results")) {
return ChargeResult.fromMap(response["results"]);
} else {
String errorMessage = response["errors"][0]["description"];
return errorMessage;
}
}
}
There's one more thing needs your attention:
When test with Android phone, don't use Stripe test cards numbers, it always gives you request failure(error codeOR-CCSEH-21). What you need to do is:
- sets android pay mode to 'test'.
- pays with your own/real card and it will pass(In below attached payment records, you can see the last payment contains my name, that's because i used my own card for the android google pay testing)
Hope it helps developers who needs it.
Haifeng Zhang
Updated on December 28, 2022Comments
-
Haifeng Zhang over 1 year
The stripe payment API call return status 200 but the amount isn't charged.
I have a Flutter application uses Stripe payment.
I have done:
- certification has been created.
- merchant id has been created.
Followed the example of
stripe_payment
, I have my native payment method below:void _handleNativePayment(String amount) async { Token token = await StripePayment.paymentRequestWithNativePay( androidPayOptions: AndroidPayPaymentRequest( totalPrice: amount, currencyCode: _currencyCode, ), applePayOptions: ApplePayPaymentOptions( countryCode: _countryCode, currencyCode: _currencyCode, items: [ ApplePayItem( type: 'final', label: _paymentLabel, amount: amount, ) ], ), ); await StripePayment.completeNativePayRequest(); }
When I run it on simulator, I can see the payment is done and can view the request on Stripe dashboard unfortunately the Payment is still 0.:
-
Joelson Rocha about 3 yearsWere you able to put it into production? I Have an ERROR: Request Failed - Unexpected developer error, please try again later. My question is: in merchantId (Google Pay MerchantId or Stripe MerchantId). And where I inform Google Pay, the integration with Stripe, Google Pay has already authorized my application for production. The documentation is not clear about the steps to put into production.