Saferpay

See example of integrating Saferpay.

Introduction

Saferpay can be used if you want to have a solution that supports the post-checkout payments. It allows the users to pay after they submit the order, within the next 30 minutes.

It's not possible to use Saferpay for the payments done before the checkout is completed.

The diagram shows how Saferpay sequence looks like when it's integrated with Emporix:

Gateway configuration

  1. To create the Spreedly receiver, execute the following request:

curl --location --request POST 'https://core.spreedly.com/v1/receivers.json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {SPREEDLY_BASIC_AUTH}' \
--data-raw '{
        "receiver": {
          "receiver_type": "saferpay",
          "hostnames": "https://test.saferpay.com",
          "credentials": [
          ]
        }
      }'

Result:

{
    "receiver": {
        "company_name": "SIX Payment Services",
        "receiver_type": "saferpay",
        "token": "CwFlWAMQaOfUqcsP8Gce2iyzNIU",
        "hostnames": "https://test.saferpay.com,https://www.saferpay.com",
        "sub_merchant_key": null,
        "state": "retained",
        "created_at": "2023-07-16T20:18:48Z",
        "updated_at": "2023-07-16T20:18:48Z",
        "credentials": [

        ],
        "ssl_certificate_token": null
    }
}
  1. Create the new payment mode, execute the following request:

curl --location --request POST 'https://api.emporix.io/payment-gateway/{TENANT}/paymentmodes/config' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {EMPORIX_AUTH_TOKEN}' \
--data-raw '{
    "code": "saferpay",
    "active": true,
    "provider": "SPREEDLY_SAFERPAY",
    "configuration": {
        "Spreedly/EnvironmentKey": "{SPREEDLY_ENV_KEY}",
        "Spreedly/AccessSecret": "{SPREEDLY_ACCESS_SECRET}",
        "Spreedly/ReceiverId" : "{SPREEDLY_RECEIVER_ID}",
        "Saferpay/BasicAuth" : "{SAFERPAY_BASIC_AUTH}",
        "Saferpay/CustomerId" : "{SAFERPAY_CUSTOMER_ID}",
        "Saferpay/TerminalId" : "{SAFERPAY_TERMINAL_ID}",
        "Saferpay/TestEnvironment" : "{SAFERPAY_TEST_ENV}",
        "Saferpay/RedirectUrl" : "{SAFERPAY_REDIRECT_URL}"
    }
}'
  • SPREEDLY_ENVIRONMENT_KEY - Spreedly environment key that you got from Emporix support team.

  • SPREEDLY_ACCESS_SECRET - Spreedly secret key that you got from Emporix support team.

  • SPREEDLY_RECEIVER_ID - The token from the receiver creation request.

  • SAFERPAY_BASIC_AUTH - The base64 of a user:password of Saferpay JSON API Basic Authentication. You can create new credentials on the Saferpay page.

  • SAFERPAY_CUSTOMER_ID - The customer ID of your Saferpay account. You can find the information on the Saferpay page.

  • SAFERPAY_TERMINAL_ID - The terminal ID of your Saferpay account.

  • SAFERPAY_TEST_ENV : expected values: true or false. Indicates whether the configuration is related to the test account or not. Based on the flag the following url is used:

    • true - https://test.saferpay.com

    • false - https://saferpay.com

  • SAFERPAY_REDIRECT_URL - The URL to which the user should be redirected after 3DS2 operation. Usually it’s the merchant's storefront. For example Emporix Demo Storefront. The following query params are automatically attached to the redirect URL:

    • orderId

    • transactionId

    • paymentModeId

Storefront implementation

Saferpay is available only for the post-checkout approach, after the actual order is done.

You can find the examples in the Emporix B2B Showcase repository.

  1. In the html part, create two buttons needed for the Saferpay:

  • A button that opens Spreedly Express modal:

<button className='large-primary-btn' onClick={openModal}>Enter Payment Info</button>
  • A button that triggers the payment process:

<FilledButton
  onClick={executePayment}
  className="mt-4 w-auto bg-yellow text-eerieBlack">
      PAY via Saferpay
</FilledButton>
  1. In the same html, add also the JS part:

const [spreedlyToken, setSpreedlyToken ] = useState(null)

useEffect(() => {
      window['SpreedlyExpress'].init(paymentMode.environmentKey, {
        "amount": props.grossValue + ' ' + props.currency,
        "company_name": "PowerZone",
        "sidebar_bottom_description": "Total Price",
      }, {
        "customerId": props.customerId
      });

      window['SpreedlyExpress'].onPaymentMethod(function(token, paymentMethod) {
        setSpreedlyToken(token)
        window['SpreedlyExpress'].unload()
      });
    }
  }, [])

  const openModal = (e) => {
    window['SpreedlyExpress'].openView()
  }

  const executePayment = async () => {
    const accessToken = localStorage.getItem(ACCESS_TOKEN)
    const headers = {
      Authorization: `Bearer ${accessToken}`
    }
    const body = {
      order : {
        id : props.orderId
      },
      paymentModeId: paymentMode.id,
      creditCardToken: spreedlyToken
    }
    const res = await api.post(`${initializePayment()}`, body, { headers })
    window.location.replace(res.data.externalPaymentRedirectURL)
  }

Result: With this configuration, the user sees a button to provide their credit card data.

  1. When a user completes the data, Spreedly sends a token via the onPaymentMethod js callback.

  2. Having this token, it's possible to display a button where the user can trigger the payment initialization, where ${initializePayment()} is resolved to /payment-gateway/${getTenant()}/payment/frontend/initialize. As a response you get an object that contains the externalPaymentRedirectURL property.

  3. You have to redirect the user to the URL. The user has to do the 3DS2 flow right on the Saferpay page.

  4. After the operation, Saferpay redirects to the SAFERPAY_REDIRECT_URL configured in payment-mode, with additional query parameters.

An example of the redirect page:

{!authorizationFinished ? 
    (
      <>We're authorizing the request...</>
    ) : 
    (
      <>
        {authorizationSuccess ? (
          <>
            Authorization finished with success <br/>
            <button className="bg-primaryBlue text-[white] px-6 py-0 h-[50px] text-[14px] leading-[14px] md:w-[400px] w-full" 
              onClick={() => {
                navigate(`/${tenant}/my-account/my-orders`)
              }}>
              CHECK YOUR ORDERS
            </button>
           
           </>
          ) : (<>Authorization failed</>)} 
        </>
    ) 
} 
const authorize = async (orderId, paymentModeId) => {
    const accessToken = localStorage.getItem(ACCESS_TOKEN)
    const headers = {
      Authorization: `Bearer ${accessToken}`
    }
    const body = {
      order : {
        id : orderId
      },
      paymentModeId: paymentModeId
    }
    try {
      const res = await api.post(`${authorizePayment()}`, body, { headers })
      setAuthorizationFinished(true)
      setAuthorizationSuccess(res.data.successful)
    } catch(ex) {
      setAuthorizationFinished(true)
      setAuthorizationSuccess(false)
    }
  }

  useEffect(() => {
      const orderId = searchParams.get('orderId')
      const paymentModeId = searchParams.get('paymentModeId')
      authorize(orderId, paymentModeId)
  },[])
  1. When the user is redirected to callback page, you should read query parameters related to the orderId and paymentModeId.

  2. Having the two parameters, you can invoke the authorize method, where ${authorizePayment()} is resolved to /payment-gateway/${getTenant()}/payment/frontend/authorize.

Result:

  • If the 3DS2 finishes with success, then the authorization response is successful: true.

  • If the 3DS2 doesn't finish with success, the authorization response is successful: false.

Last updated

Was this helpful?