John Code
John Code

Reputation: 675

Accepting payments in Xamarin Forms with Stripe's Payment Intent API

I have implemented payment in my back-end using Stripe.net, Now I have a mobile client writen in Xamarin Which I want to approve credit card payments with. But All of the examples I find online use the Charge API. I use the PaymentIntentAPI in my back-end and this returns a client secret as requested.

My question is: How do I confirm the payment using the Stripe.net package and the PaymentIntent API ?

Here is how it is done on android with java:

 stripe = new Stripe(
                    context,
                    PaymentConfiguration.getInstance(context).getPublishableKey()
            );
            stripe.confirmPayment(this, confirmParams);

Using the old charges API in dotnet, here is how it is done:

 StripeConfiguration.SetApiKey("pk_test_xxxxxxxxxxxxxxxxx");

var tokenOptions = new StripeTokenCreateOptions()
{
    Card = new StripeCreditCardOptions()
    {
        Number = cardNumber,
        ExpirationYear = cardExpYear,
        ExpirationMonth = cardExpMonth,
        Cvc = cardCVC
    }
};

var tokenService = new StripeTokenService();
StripeToken stripeToken = tokenService.Create(tokenOptions);

Upvotes: 7

Views: 3565

Answers (2)

Abdelrahman Elborey
Abdelrahman Elborey

Reputation: 251

Ok, so since I really struggled to get this working, I though of sharing it with you guys here, maybe it will be useful to someone who got stuck like myself, basically you need to collect credit card details from you users in a regular xamarin form, then use the below code to confirm the paymentintent using the credit card details:

  • first create a paymentIntent on your backend server as described in stripe docs, and return the paymentIntent Id and client secret to your xamarin forms app.
  • create a paymentIntentConfirmOptions

 var paymentConfirmOptions = new PaymentIntentConfirmOptions
                {
                    ClientSecret = createPaymentIntentResponse.ClientSecret,
                    Expand = new List<string> { "payment_method" },
                    PaymentMethodData = new PaymentIntentPaymentMethodDataOptions
                    {
                        Type = "card",
                        BillingDetails = new    PaymentIntentPaymentMethodDataBillingDetailsOptions
                        {
                            // Add Extra Info                            
                        }
                    },
                    ReturnUrl = "payments-example://stripe-redirect"
                };

  • Set credit card options in the PaymentIntentConfirmOptions :

paymentConfirmOptions.AddExtraParam("payment_method_data[card][number]", "1234567890353543");
                paymentConfirmOptions.AddExtraParam("payment_method_data[card][exp_month]", "12");
                paymentConfirmOptions.AddExtraParam("payment_method_data[card][exp_year]", "23");
                paymentConfirmOptions.AddExtraParam("payment_method_data[card][cvc]", "123");

  • Then confirm the payment : var result = await paymentIntentService.ConfirmAsync(PaymentIntentId, paymentConfirmOptions);

Upvotes: 2

ttmarek
ttmarek

Reputation: 3240

The approach depends a bit depending on your requirements. If you plan to accept only U.S and Canadian cards then the simplest approach would be to confirm the PaymentIntent server-side as described in this guide here:

https://stripe.com/docs/payments/without-card-authentication

The gist is that you collect the credit card information client-side (preferably by tokenizing the details using one of our client-libraries), then call the PaymentIntents API much like you would the Charges API:

            var options = new PaymentIntentCreateOptions
            {
              Amount = 1099,
              Currency = "usd",
              PaymentMethodId = request.PaymentMethodId,

              // A PaymentIntent can be confirmed some time after creation,
              // but here we want to confirm (collect payment) immediately.
              Confirm = true,

              // If the payment requires any follow-up actions from the
              // customer, like two-factor authentication, Stripe will error
              // and you will need to prompt them for a new payment method.
              ErrorOnRequiresAction = true,
            };

            paymentIntent = service.Create(options);

The key parameters here are:

  • Confirm: needs to be set to true so that the payment is processed right away.
  • ErrorOnRequiresAction: needs to be set to true to prevent the payment from entering a state where it expects some form of authentication (e.g. 3D Secure)

If SCA and global regulatory requirements are a concern. Then you will need to find a way to confirm the payment client-side so users can authenticate a payment if they need to. Right now, the available integration paths are unfortunately quite limited for hybrid mobile technologies like Cordova, React Native, and Xamarin. Generally speaking there are two paths you can take:

run Stripe.js in a WebView

This would allow you to use all the methods described here: https://stripe.com/docs/js, and follow our default integration path for accepting payments: https://stripe.com/docs/payments/accept-a-payment. For the Xamarin side of things a good place to start would be the official WebView example: https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/workingwithwebview/.

build a bridge to Stripe's native iOS and Android SDKs

This is a bit more complex than running Stripe.js in a WebView, but would likely be more performant and give a slightly more polished user experience. With this approach you would build a bridge into Stripe's Android and iOS SDKs using the approaches outlined here: https://devblogs.microsoft.com/xamarin/binding-ios-swift-libraries/ (iOS), https://learn.microsoft.com/en-us/xamarin/android/platform/binding-java-library/ (Android)

Upvotes: 3

Related Questions