当使用 Stripe 确认付款意向时,资金被冻结但 API returns 失败

When confirming payment intent with Stripe the funds are being hold but the API returns as failed

我试图在旅行完成之前保留客户卡上的资金。

在服务器上:

> const capture = await stripe.paymentIntents.create({
>             customer: stripeId,
>             amount: amount,
>             currency: "gbp",
>             payment_method: paymentId,
>             receipt_email: email,
>             confirm: true,
>             capture_method: "manual",
>             setup_future_usage: "off_session",
>             use_stripe_sdk: true,
>         });

付款意向返回状态为“requires_action”,因此我尝试确认应用程序中的资金持有情况:

>  final PaymentConfiguration paymentConfiguration =
> PaymentConfiguration.getInstance(requireContext());
>             PaymentLauncher paymentLauncher = PaymentLauncher.Companion.create(this,
> paymentConfiguration.getPublishableKey(),
> paymentConfiguration.getStripeAccountId(), this);
> 
> final ConfirmPaymentIntentParams confirmParams = ConfirmPaymentIntentParams.createWithPaymentMethodId(paymentMethodId,
> clientSecret);
>             paymentLauncher.confirm(confirmParams);

正在确认资金,支付意向更新状态为“requires_capture”,但支付结果回调return失败。这张卡并不真的需要 3DS 但它 return "requires_action" 所以我需要确认一下。在另一张确实需要 3DS 的卡上,此方法有效。

@Override
>     public void onPaymentResult(@NonNull PaymentResult paymentResult) {
>         if (paymentResult instanceof PaymentResult.Completed) {
>         } else if (paymentResult instanceof PaymentResult.Canceled) {
>         } else if (paymentResult instanceof PaymentResult.Failed) {
>             Throwable error = ((PaymentResult.Failed) paymentResult).getThrowable();error.getMessage());
>         }
>     }

我最终使用了条纹 API:

检查返回的付款意向的状态,如果是 requires_action 或 requires_confirmation 使用此:

Stripe stripe = new Stripe(this, publishable key);
ConfirmPaymentIntentParams confirmPaymentIntentParams = ConfirmPaymentIntentParams.create(response.getString("secret"));
stripe.confirmPayment(this, confirmPaymentIntentParams);
    
@Override
public void onActivityResult(int requestCode, int resultCode, @org.jetbrains.annotations.Nullable Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
                stripe.onPaymentResult(requestCode, data, new ApiResultCallback<PaymentIntentResult>() {
                    @Override
                    public void onSuccess(@NonNull PaymentIntentResult paymentIntentResult) {
                        StripeIntent.Status status = paymentIntentResult.getIntent().getStatus();
                        if (status != null) {
                            switch (status) {
                                case Succeeded:
                                case RequiresCapture:
                                    //all good
                                    break;
                                case RequiresAction:
                                case RequiresConfirmation:
                                    //error i guess
                                    break;
                                case RequiresPaymentMethod:
                                    //no funds
                                    break;
                                case Canceled:
                                    checkPayment();
                                    break;
                            }
                        } else {
                            checkPayment();
                        }
                    }
        
                    @Override
                    public void onError(@NonNull Exception e) {
                        //show error
                    }
                });
            }