Migration to SCA-Ready ProcessOut.js

With new DSP2 regulations in Europe and Strong Customer Authentication, merchants must update their payments form to comply with new rulings. Fortunately, ProcessOut’s integration and SDKs provide an easy and straightforward migration, removing much of the compliance hassle.

Migration strategy to ProcessOut SCA-Ready

The migration mostly involves changes to your front-end. ProcessOut’s API objects don’t change: Invoices, Transactions, Customers and Subscriptions are left unchanged.

  • 1— Update your SDKs version
  • 2— (optional) Send the channel used to process the payment (web, ios or android)
  • 3— Make use of ProcessOut.js to process the payment from the client side and handle authentication if required
  • 4— Confirm the payment from your backend

1. Upgrade your SDKs

Make sure to upgrade the SDKs versions to get access to the most up-to-date helpers exposed. You can find some handy-links below to visit our official SDKs:

2. Send the channel used to process the payment

Although optional, we recommend you send the channel on which the user will process the payment. This is mainly used during authentication to make the most out of the native 3DS2 SDKs and flows.

If not provided, the channel will always default to web, even if you’re using our mobile SDKs.

curl -X POST https://api.processout.com/invoices \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB \
    -d name="Awesome invoice" \
    -d amount="4.99" \
    -d currency=USD \
    -d device.channel=web
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");

client.newInvoice().create({
    name:     "Awesome invoice",
    amount:   "4.99",
    currency: "USD",
    device:   client.newInvoiceDevice({
        channel: "web" // optional; can be web, ios or android
    })
}).then(function(invoice) {
    // invoice is our newly created resource

}, function(err) {
    // An error occured

});
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")

invoice = client.new_invoice().create({
    "name":     "Awesome invoice",
    "amount":   "4.99",
    "currency": "USD",
    "device":   client.new_invoice_device({
        "device": "web" # optional; can be web, ios or android
    })
})
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")

invoice = client.invoice.create(
    name:     "Awesome invoice",
    amount:   "4.99",
    currency: "USD",
    device:   client.invoice_device.new(
        channel: "web" # optional; can be web, ios or android
    )
)
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");

$invoice = $client->newInvoice()->create(array(
    "name"     => "Awesome invoice",
    "amount"   => "4.99",
    "currency" => "USD",
    "device"   => $client->newInvoiceDevice(array(
        "channel" => "web" // optional; can be web, ios or android
    ))
));
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")

iv, err := client.NewInvoice().Create(processout.InvoiceCreateParameters{
    Invoice: &processout.Invoice{
        Name:     processout.String("Awesome invoice"),
        Amount:   processout.String("4.99"),
        Currency: processout.String("USD"),
        InvoiceDevice: client.NewInvoiceDevice(processout.InvoiceDevice{
            // optional; can be web, ios or android
            Channel: processout.String("web"),
        }),
    },
})

3. Process payments with ProcessOut.js

Prior to SCA & 3DS2, you had two ways of processing payments: with 3DS authentication, or without. The new ProcessOut.js merges these two processing ways into one, effectively making it possible to transparently handle dynamicly triggered 3DS1 and 3DS2 authentications.

Migrate flow with 3DS

If you were already using 3DS for your transactions before: good news! You’re almost ready for SCA and 3DS2. The only thing you’ll need to change is to call makeCardPayment on ProcessOut.js instead of the 3DS1-only authenticate method.

Before
client.threeDS.authenticate({
    // Set the invoice ID
    invoiceID: "iv_lEZFFcQg5Wwp...",
    // And the source
    source:    "card_Tpu6ZOCDu1..."
}, function(invoiceID) {
    // Successful authentication

}, function(err) {
    // Failed authentication

});

After
client.makeCardPayment(
    "iv_lEZFFcQg5Wwp...", 
    "card_Tpu6ZOCDu1...", {

    // Set to true if you want to keep
    // a similar behavior as before 
    // where you confirm payments in 
    // your backend
    authorize_only: true, 
},
function(invoiceID) {
    // Successful authentication

}, function(err) {
    // Failed authentication

});

Migrate flow without 3DS

If you weren’t making use of 3DS before, you’ll need to update your Checkout a bit:

Migrate flow for MIT (Merchant Initiated Transactions)

If you’re operating subscriptions, subsequent transactions fall outside of the SCA scope and don’t actually require any 3DS challenge to be performed.

No code change is required from your side for these transactions. In order to maximize the chances of ProcessOut to properly detect these transactions, you might want to also send merchant_initiator_type="recurring" during the Invoice creation to flag the transactions as being a MIT recurring.

curl -X POST https://api.processout.com/invoices \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB \
    -d name="Awesome invoice" \
    -d amount="4.99" \
    -d currency=USD \
    -d merchant_initiator_type=recurring
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");

client.newInvoice().create({
    name:     "Awesome invoice",
    amount:   "4.99",
    currency: "USD",

    merchantInitiatorType: "recurring"
}).then(function(invoice) {
    // invoice is our newly created resource

}, function(err) {
    // An error occured

});
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")

invoice = client.new_invoice().create({
    "name":     "Awesome invoice",
    "amount":   "4.99",
    "currency": "USD",

    "merchant_initiator_type": "recurring"
})
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")

invoice = client.invoice.create(
    name:     "Awesome invoice",
    amount:   "4.99",
    currency: "USD",

    merchant_initiator_type: "recurring"
)
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB");

$invoice = $client->newInvoice()->create(array(
    "name"     => "Awesome invoice",
    "amount"   => "4.99",
    "currency" => "USD",

    "merchantInitiatorType" => "recurring"
));
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_mah31RDFqcDxmaS7MvhDbJfDJvjtsFTB")

iv, err := client.NewInvoice().Create(processout.InvoiceCreateParameters{
    Invoice: &processout.Invoice{
        Name:     processout.String("Awesome invoice"),
        Amount:   processout.String("4.99"),
        Currency: processout.String("USD"),

        MerchantInitiatorType: processout.String("recurring"),
    },
})

4. Confirm the payment from your backend

As payments can now be authorized and/or captured from the client-side, the payment confirmation/capture isn’t required from your backend anymore. However, we strongly advise you to keep using the same code in your backend to check the transaction is in the correct state before doing the final order validation.

Learn more about capturing payments in your backend ↗, checking for error codes ↗ and listening for our webhooks about payment updates ↗.