Skip to main content

Payment through datatrans

::: Configuration Options for our Datatrans Integration :::

Unchained supports both the old XML based legacy API of Datatrans payment process overview and the new transactionId centric API based on JSON If you already have Datatrans chances are high you're still using the legacy API and so you will have to use the legacy Datatrans Unchained Plugin. If you're starting fresh, you will be using the new one.

Activate either of those in your project by selecting to import one (and only one):

  • Old Legacy API (v1): import '@unchainedshop/core-payment/plugins/datatrans';
  • Current API (v2): import '@unchainedshop/core-payment/plugins/datatrans-v2';

The rest of this page will center around the new v2 plugin. If you need support for the legacy plugin, check the source of the plugin and if questions arise, send us an e-mail.

Setup Plugin v2

Environment variables

You have to set DATATRANS_SECRET and DATATRANS_SIGN_KEY on build-time based on the configuration on your Datatrans Merchant Account:

NAMEDefault ValueAllowed Values
DATATRANS_SECRET
DATATRANS_SIGN_KEY
DATATRANS_SIGN2_KEY{DATATRANS_SIGN_KEY}
DATATRANS_SECURITYdynamic-sign'', 'static-sign', 'dynamic-sign'
DATATRANS_API_ENDPOINThttps://api.sandbox.datatrans.com
DATATRANS_WEBHOOK_PATH{ROOT_URL}/payment/datatrans/webhook
DATATRANS_SUCCESS_PATH{ROOT_URL}/payment/datatrans/success
DATATRANS_ERROR_PATH{ROOT_URL}/payment/datatrans/error
DATATRANS_CANCEL_PATH{ROOT_URL}/payment/datatrans/cancel
DATATRANS_RETURN_PATH{ROOT_URL}/payment/datatrans/return

In order to activate live payments, you will have to set the DATATRANS_API_ENDPOINT to the non-sandbox URL.

Configure Datatrans

Instantiate a provider

When adding a datatrans payment provider either through the Admin UI or with the createPaymentProvider, you will need to tell it with which merchantId it authenticates requests against the Datatrans API, the configuration parameters you can set are:

KEYDefault ValueAllowed Values
merchantId
settleInUnchained1"1", ""
marketplaceSplit"SUBMERCHANTID;DISCOUNT_ADAPTER_KEY;OPTIONAL_SHARE_PERCENTAGE"

If you don't set the merchantId on the provider, Unchained tries to read it from the environment variable DATATRANS_MERCHANT_ID

Unchained Engine supports Datatrans Marketplace Integration:

You can add multiple marketplaceSplit entries to configure marketplace payments. See https://docs.datatrans.ch/docs/marketplace-payments#section-settlement-splits for more information. settleInUnchained has to be 1 if you want to use marketplace features because split happens at settlement.

The marketplace feature depends on a custom discount that pre-calculates the comissions before checkout. That adapter key then needs to be referenced in the payment configuration.

You can also configure more than one sub merchant and then split the "pie" based on OPTIONAL_SHARE_PERCENTAGE, keep in mind that if you have more than one, the sum of all OPTIONAL_SHARE_PERCENTAGE needs to be 100.

Of course, you can add any additional properties to the configuration if you need that to filter payment providers.

If you want to use a deferred settlement of Unchained Engine for only some specific payment providers, you will have to instantiate multiple providers and select the correct one from the frontend, so in these cases, it helps to add additional properties server-side that may help the UI distinguish the providers.

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.