You can see an example of the Stripe implementation in our Upodi Stripe Sample on our Github.

1. Tokenizing cards with Stripe

To tokenize cards with Stripe you can use Stripe.js (Recommended) or the API for Payment Methods.

Stripe.js:

stripe.createPaymentMethod('card', card, {
            billing_details: {
                name: fullName,
                phone: phone,
                email: email,
                address: {
                    country: country,
                    city: city,
                    line1: address,
                }
            }
        }).then(function (result) {
            // Handle result.error or result.paymentMethod
            if (typeof result.paymentMethod !== "undefined") {
                var successElement = document.getElementById("success-block");
                            successElement.innerHTML += 'Success! Payment method ID: ' +        result.paymentMethod.id;
            }
            if (typeof result.error !== "undefined") {
                var errorElement = document.getElementById("error-block");
                errorElement.innerHTML += 'Success! Payment method id:' + 
                result.error.message;
            }
        });

In case of a success you receive a result.PaymentMethod: pm_rt35386w6sndty

👍

PSD2

As a good practice in PSD2 it is recommended that you implement 3D Secure in your save card procedure from 14th of September and going forward.

2. Attach to customer

It is optional whether you want to attach the Payment Method to a customer, but it is recommended to do so according to Stripe.

Create Customer:

# Create a Customer:
curl https://api.stripe.com/v1/customers \
   -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
   -d email="[email protected]" \
   -d source=tok_60OX9jRXUI6WzLI0V2SFxUjr
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");

// Token is created using Checkout or Elements!
// Get the payment token ID submitted by the form:
$token = $_POST['stripeToken'];

// Create a Customer:
$customer = \Stripe\Customer::create(array(
  "email" => "[email protected]",
  "source" => $token,
));
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
StripeConfiguration.SetApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");

// Token is created using Checkout or Elements!
// Get the payment token submitted by the form:
var token = model.Token; // Using ASP.NET MVC

var customers = new StripeCustomerService();
var charges = new StripeChargeService();

var customer = customers.Create(new StripeCustomerCreateOptions {
  Email = "[email protected]",
  SourceToken = token
});

Once you have created the customer, you can attach the pm_token:

# attach payment method to customer:
curl https://api.stripe.com/v1/payment_methods \
  -u sk_test_Y67DOBo7IERJKXKBiTjXrP5X: \
  -d customer=cus_FmguAmvkiqr3wh \
  -d payment_method=pm_123456789 \
  -H "Stripe-Account: {{CONNECTED_STRIPE_ACCOUNT_ID}}"
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
\Stripe\Stripe::setApiKey('sk_test_Y67DOBo7IERJKXKBiTjXrP5X');

$payment_method = \Stripe\PaymentMethod::create([
  'customer' => 'cus_FmguAmvkiqr3wh',
  'payment_method' => 'pm_123456789',
], ['stripe_account' => '{{CONNECTED_STRIPE_ACCOUNT_ID}}']);
// Set your secret key: remember to change this to your live secret key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
StripeConfiguration.ApiKey = "sk_test_Y67DOBo7IERJKXKBiTjXrP5X";

var paymentMethodOptions = new PaymentMethodOptions() {
  CustomerId = "cus_FmguAmvkiqr3wh",
  PaymentMethodId = "pm_123456789",
};

var paymentMethodService = new PaymentMethodService();
var requestOptions = new RequestOptions() {
  StripeConnectAccountId = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
};

PaymentMethod paymentMethod = paymentMethodService.Create(paymentMethodOptions, requestOptions);

3. Send Stripe token to Upodi

To create a payment method for Stripe token, make a POST request to /paymentmethods/:customerid/ with a body using the createpaymentmethod request object. Upodi actually supports both the cus and the pm tokens, but we suggest posting the pm_ token to easier identify which payment method is being used in Upodi.

{
  "type" : 64 /* PureTokenBased = 64 */,
  "makedefault" : "true", /* will make the payment method default on the customer */
  "puretoken" : { 
    "token" : "pm_C9VhJ6qk0qkKqI", /* Stripe customer ID */
    "paymentgateway" : "stripe" 
  }
}

4. Prepare for 3D secure required

If Strong Customer Authentication is suddenly required the invoice in Upodi will be marked as pending response. This fires off a webhook from Upodi, which you have to grab at your end.

Step 1. Grab webhook from Upodi

Setup a webhook in the Upodi developers section.

Pending Response webhook:

{  
   "ID":"8405c2cc-cf36-4984-ac0f-f51e748a763f",
   "Time":132107805174134235,
   "Signature":"NThhM2U2MDItMzk1Yi00M2YwLWE0NDYtNzM2MzI3YmI1OGEw",
   "Action":"Customer needs to take action",
   "Issuer":{  
      "Url":"/Invoice/stripe_3d_auth_required/afd58e3e-4da6-4f38-aeaf- 18570a7bdd25",
      "Identifier":"afd58e3e-4da6-4f38-aeaf-18570a7bdd25"
   },
   "Data":{  
      "PaymentMethodId":"card_1F6w5hI27jCCaRHIZpgXmVnk",
     "IntentSecret":"pi_1F9XBAI27jCCaRHI02kDAd1I_secret_RJAajlr1fq7EJflVatzmw1f9v"
   },
   "Type":"Invoice"
}

Step 2. Create on-session payment

Both of the values "PaymentMethodId":"card_1F6w5hI27jCCaRHIZpgXmVnk" and "IntentSecret":"pi_1F9XBAI27jCCaRHI02kDAd1I_secret_RJAajlr1fq7EJflVatzmw1f9v" should be used to make an on-session payment in Stripe.js:

var paymentmethodId = document.getElementById('paymentMethodId').value;
    var clientSecret = document.getElementById('clientSecret').value;
    stripe.handleCardPayment(
            clientSecret,
            {
            payment_method: paymentmethodId,
            }
    ).then(function(result) {
        if (result.error) {
        console.log(result.error);

Step 3. Connect a Stripe webhook to Upodi

In order for Upodi to receive notice of this on-session payment, setup a webhook in Stripe pointing to your Upodi tenant. Go to your developers section in Stripe.

Setup a Webhook in Stripe pointing to UpodiSetup a Webhook in Stripe pointing to Upodi

Setup a Webhook in Stripe pointing to Upodi

Select events payment_intent.payment_failed and payment_intent.succeeded.

Now Upodi gets notified when the Strong Customer Authentication has been carried out and marks the invoice paid or failed accordingly. When this step has been carried out the Strong Customer Authentication is automatically stored with the Payment Method, and should secure the payment method for future Merchant Initiated Transactions.