Implementing Stripe in Xamarin

If you want to take payments from your customers, via your Xamarin app, you can use a payment processor such as Stripe to accomplish this. However there are many hurdles to overcome, to ensure you develop a secure solution that adheres to the App Store’s rules, and ensure you either meet or don’t have to worry about PCI compliance.

App Store Regulations

Before we go any further, all app stores, have rules regarding payments. If you sell in-tangible products, you have to use the app store’s payment systems. They will typically take a 30% cut in revenue, which is incredibly steep, but your app will not be compliant otherwise. If you sell tangible products, such as physical goods you ship, or services, then you can not use their payment system, and must provide your own. Check out Apples’ In-App Purchase and Google’s In-App Billing. If you are using Stripe, it is assumed you are selling physical goods and/or services.

PCI Compliance

PCI compliance depending upon location is generally not (but can be) a law, but a part of the terms and service agreements you accept with your payment processor. It is a set of standards you must adhere to, to ensure you keep customers credit card information safe. To see what your responsibilities are you want to check out the PCI Self Assessment Checklists. This may all seem overwhelming, so to help with this payment processors such as Stripe aim to take most of the burden away from you. You still want to do the checklists, and ensure you comply.

Stripe Integration

API Keys

To process payments via stripe you will need a Publishable Key and a Secret Key. When you login to your Stripe account, create the keys, and first use the Test keys, to test your payment system first, before going live. Note: When you are using test keys, you need to use the Testing cards, listed by Stripe.

UI Controls

The first step, is accepting credit card information in your mobile app. Stripe do offer native components for this, but nothing for Xamarin. As such we will want to create our own Xamarin controls to accept credit card information. It can be as simple as this example in Xamarin.Forms.

<StackLayout>
    <Entry Text="{Binding CreditCardNumber}" Placeholder="Enter your credit card number"></Entry>
    <StackLayout Orientation="Horizontal">
        <Entry Text="{Binding ExpiryDate}" Placeholder="Expiry date"></Entry>
        <Entry Text="{Binding CVV}" Placeholder="CVV"></Entry>
    </StackLayout>
</StackLayout>

Of course, you will want to make yours look much nicer. But this gathers the 3 basic things you need to create a Stripe Token. It will also be wise to do some validation checks on your UI, to ensure they enter their information in the correct format.

Create Stripe Token

When you pass the above information to Stripe, you get a token in return. This token, allows you to charge an amount to the credit card, through your account.

In your mobile app download the official Stripe nuget package. You can then create a Stripe Token, with the following function.

public string CreateToken(string cardNumber, string cardExpMonth, string cardExpYear, string cardCVC)
{
    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);

    return stripeToken.Id; // This is the token
}

You will use your Publishable Key here. DO NOT put your secret key in your app. There is no way you can keep it safe, and it can be reversed engineered, even if you obfuscate or encrypt it, generally because you will have to have the encryption key also public so your app can use it. The secret key can only be kept server side.

Securing Sensitive Information

Using this approach, the credit card information, never goes through any of your infrastructure or servers, however there is reason for extra caution.

  • Could be stored in logs. Do not log any of these HTTPS calls.
  • Could be caught in crash reports. Use filters, to ensure these fields don’t get sent to something like HockeyApp.
  • Could be seen on background preview screenshots, when switching between apps. See Secure Background Screen Preview In Xamarin
  • Clear these fields immediately after you have received your token. Also use OnDisappearing to clear all of these fields, when they move away from the screen.

Do not log or store credit card information, anywhere in your app.

Web API

Now that we have a token, we need to make a charge against it. However, you can only make a charge against a Stripe Token, if you have your secret key. The only way to keep that secure, is to have it on your server. Hence we need to create our own API, or expand upon an existing one. First I create a dto for transfering information in to my API.

public class PaymentModel
    {
        public string Token { get; set; }
        public decimal Amount { get; set; }
    }

Then we create a controller, with a POST action, to receive this token, and make a charge. You notice we only receive the token here, no credit card information is coming to the server at all. You will want to make sure your API is using HTTPS and you provide any further authentication as necessary.

[Route("api/[controller]")]
public class PaymentController : Controller
{
    [HttpPost]
    public IActionResult Post([FromBody]PaymentModel payment)
    {
        // You can optionally create a customer first, and attached this to the CustomerId
        var charge = new StripeChargeCreateOptions
        {
            Amount = Convert.ToInt32(payment.Amount * 100), // In cents, not dollars, times by 100 to convert
            Currency = "usd", // or the currency you are dealing with
            Description = "something awesome",
            SourceTokenOrExistingSourceId = payment.Token
        };

        var service = new StripeChargeService("sk_test_xxxxxxxxxxxxx");

        try
        {
            var response = service.Create(charge);

            // Record or do something with the charge information
        }
        catch (StripeException ex)
        {
            StripeError stripeError = ex.StripeError;
               
            // Handle error
        }

        // Ideally you would put in additional information, but you can just return true or false for the moment.
        return Ok(true); 
    }
}

Calling The API

From our Xamarin app, we can call the WebAPI with the following code. Make sure you create a copy of the PaymentModel to your Xamarin app.

HttpClient client = new HttpClient();
await client.PostAsync("https://myname.azurewebsites.net/api/payment", 
                       new StringContent(JsonConvert.SerializeObject(new PaymentModel()
                                                                     { Amount = 80.56M,
                                                                       Token = "whatYouReceivedFromStripe" 
                                                                     }),
                                         Encoding.UTF8,
                                         "application/json"));

One, more secure option, would be to have a list of products on your server, and send a product Id, instead of the amount. This way the server would control the pricing not the app.

Notice

You are dealing with sensitive information, and must handle this with care. I want to mention that you should read the terms and policies of Stripe and PCI standards security council, to determine what applies to your situation. I have given advice with my best intentions, but you need to ensure it complies with your own requirements.


XAMARIN.FORMS MONTHLY NEWSLETTER

JOIN 1,100+ SUBSCRIBERS

  1. Don't miss out on updates
  2. The latest info from this site, Xamarin and the community
  3. Unsubscribe at any time*

* We use MailChimp, with double opt-in, and instant unsubscribe

Microsoft MVP | Xamarin MVP | Xamarin Certified Developer | Exrin MVVM Framework | Xamarin Forms Developer | Melbourne, Australia

Related Posts