Skip to main content

Datatrans

Unchained payment plugin for Datatrans, a Swiss payment service provider supporting multiple payment methods.

Installation

Express:

import express from 'express';
import '@unchainedshop/plugins/payment/datatrans-v2';
import { datatransHandler } from '@unchainedshop/plugins/payment/datatrans-v2/handler-express';

const { DATATRANS_WEBHOOK_PATH = '/payment/datatrans/webhook' } = process.env;

// IMPORTANT: Use express.text for Datatrans signature verification
app.use(DATATRANS_WEBHOOK_PATH, express.text({ type: 'application/json' }), datatransHandler);

Fastify:

import '@unchainedshop/plugins/payment/datatrans-v2';
import { datatransHandler } from '@unchainedshop/plugins/payment/datatrans-v2/handler-fastify';

const { DATATRANS_WEBHOOK_PATH = '/payment/datatrans/webhook' } = process.env;

fastify.register((s, opts, registered) => {
s.addContentTypeParser(
'application/json',
{ parseAs: 'string', bodyLimit: 1024 * 1024 },
s.defaultTextParser,
);
s.route({
url: DATATRANS_WEBHOOK_PATH,
method: 'POST',
handler: datatransHandler,
});
registered();
});

Create Provider

mutation CreateDatatransProvider {
createPaymentProvider(
paymentProvider: {
type: GENERIC
adapterKey: "shop.unchained.payment.datatrans"
configuration: [
{ key: "merchantId", value: "your-merchant-id" }
]
}
) {
_id
}
}

Environment Variables

VariableDefaultDescription
DATATRANS_SECRET-API secret (required)
DATATRANS_SIGN_KEY-Signing key (required)
DATATRANS_SIGN2_KEY{DATATRANS_SIGN_KEY}Secondary signing key
DATATRANS_SECURITYdynamic-sign'', 'static-sign', 'dynamic-sign'
DATATRANS_API_ENDPOINThttps://api.sandbox.datatrans.comAPI endpoint (use non-sandbox for production)
DATATRANS_WEBHOOK_PATH/payment/datatrans/webhookWebhook endpoint path
DATATRANS_SUCCESS_PATH/payment/datatrans/successSuccess redirect path
DATATRANS_ERROR_PATH/payment/datatrans/errorError redirect path
DATATRANS_CANCEL_PATH/payment/datatrans/cancelCancel redirect path
DATATRANS_RETURN_PATH/payment/datatrans/returnReturn redirect path
DATATRANS_MERCHANT_ID-Default merchant ID (fallback if not set in provider config)

Provider Configuration

KeyDefaultDescription
merchantId-Datatrans merchant ID (required)
settleInUnchained1Enable settlement in Unchained ("1" or "")
marketplaceSplit-Marketplace split config: "SUBMERCHANTID;DISCOUNT_ADAPTER_KEY;SHARE_PERCENTAGE"

Marketplace Integration

Unchained supports Datatrans Marketplace payments. See Datatrans Marketplace docs for details.

  • Add multiple marketplaceSplit entries for multi-merchant splits
  • settleInUnchained must be 1 for marketplace features
  • The marketplace feature requires a custom discount adapter to pre-calculate commissions

Usage in the Frontend

You can easily follow the documentation on redirect lightbox and secure fields.

Mode: Redirect / Lightbox Instructions

Follow secure fields and where it says you have to initialize a transaction you have to call one of these mutations:

Cart Checkout:

signPaymentProviderForCheckout(
orderPaymentId: "order payment id of the cart you want to checkout"
)

To get the order payment id of the current active cart of the logged in user you can

me {
cart {
payment {
_id
}
}
}

Payment credentials registration (without payment/checkout):

signPaymentProviderForCredentialRegistration(
paymentProviderId: "payment provider id that you instantiated before"
)

For both signPaymentProviderForCheckout and signPaymentProviderForCredentialRegistration you will receive a JSON stringified object that looks like:

{
location: "https://pay.sandbox.datatrans.com/v1/start/xyz1234..",
transactionId: "xyz1234.."
}

That's when you can either redirect to the location for "Redirect" mode or use the transactionId with the "Lightbox" mode to finalize the Payment as shown here: https://docs.datatrans.ch/docs/redirect-lightbox#section-redirect-integration and https://docs.datatrans.ch/docs/redirect-lightbox#section-lightbox-integration.

When a successful payment is finished, Datatrans will call the Datatrans webhook of Unchained Engine server-side (DATATRANS_WEBHOOK_PATH), Unchained Engine will look up the transaction, do some validity checks and then call checkoutCart for you, At checkoutCart stage, Unchained Engine will settle the payment and also store the payment credential alias for convenience (fast) in further checkouts. Datatrans will also almost immediately redirect to DATATRANS_SUCCESS_PATH with the transactionId and in the query parameter.

If for some reason the webhook has not been called at all or failed a checkout server-side at a very early stage, it could happen that when success path is loaded, the cart is not checked out yet but the payment is already authorized and authenticated (not settled). In those cases you should fallback to client-side cart checkout by calling:

checkoutCart(
orderId: "order id from query parameter",
paymentContext: { transactionId: "transaction id from query parameter" }) {
_id,
status
}

This gives Unchained Engine a (second) chance to process and settle the payment. That's how you build rock-solid payment flows in shaky networks.

Mode: Secure Fields

To let Unchained call the secureFieldsInit method during transaction creation, provide { "useSecureFields": true } via the transactionContext field to signPaymentProviderForCheckout or signPaymentProviderForCredentialRegistration. Also you will have to authorize-split a secure fields transaction in order to checkout, for that you will have to call checkoutCart after form submission with a special object authorizeAuthenticated:

checkoutCart(
orderId: "order id from query parameter",
paymentContext: { transactionId: "transaction id from query parameter", "authorizeAuthenticated": { "CDM": "...", "3D": "..." } }) {
_id,
status
}

This will instruct Unchained to authorize an unauthorized transaction before trying to settle it. If you don't have CDM or 3D props to send along, just send an empty object.

Mode: Mobile SDK

To enable mobile tokens during checkout as stated here, send a special transactionContext to signPaymentProviderForCheckout: { "option": { "returnMobileToken": true } }

Advanced integration features

Restrict payment method selection in redirect: You can send any additional properties to /v1/transactions/init by setting properties on the context input fields for eg. if you want to restrict payment methods during checkout you could send { "paymentMethods": ["VIS"] } as value for transactionContext in signPaymentProviderForCheckout to restrict checkout with that provider to VISA credit cards,

Checkout with alias: Just simply do checkoutCart without initializing a transactionId. If the user has valid stored payment credentials for the datatrans payment provider, the plugin will try to use that information and directly checkout and settle the payment.

Asynchronous Webhook: As stated here there is the possibility of asynchronous webhooks. Don't enable this, else you will have to "poll" the order status after checkout as webhook-based checkout could still be in-flight and you will miss out on a whole category of errors for the sake of speeding up 1s of processing time.

Adapter Details

PropertyValue
Keyshop.unchained.payment.datatrans
TypeGENERIC
Sourcepayment/datatrans-v2/