Skip to main content

Processing Payments

Hellgate® is a payment orchestration and automation system that seamlessly integrates payment service providers into a unified payment experience. However, since we can integrate not only payment service providers, but also other parties that process transactions instructed by Hellgate, we have given these external parties the name "processor".

Processors

Processors execute transactions that are then integrated into the payment experience in Hellgate. They take care of all technical aspects of the transaction, but also encapsulate regulatory issues if needed. Examples of processors are modern payment services such as Stripe or Adyen, but also more common organisations in the payment environment such as banks, card schemes, risk and fraud service providers.

Hellgate has natively integrated a variety of processors such as Stripe, Adyen or FiServ, which can be used "out of the box" with a little configuration. In addition to native integrations of processors, Hellgate also allows you to develop your own integrations and include them in the payment experiences. Each processor is integrated into Hellgate using a plugin as part of the extension framework.

Flows

The transactions executed by the processors are combined into so-called flows, which give them a sequence as well as business logic and thus meaning. Flows are typically deeply encoded in gateway solutions, which make them cumbersome to maintain and hard to adapt.

In Hellgate Flows are just another facet of the configuration. You can choose from the natively integrated flows that ship with Hellgate and cover the standard payment use-cases, or you add your own flows.

In order to allow merchants to specifically adapt to commerce situation, Hellgate provides the Flow Matrix, which is a rule-based decision engine, to select the flow to execute by context.

The following example shows the use of a flow in the context of payments:

Each payment request is a qualified set of data, which was presented by the merchant or was complemented through consumer interaction. This set of data then enables the flow matrix to decide which flow to apply. The flow itself then executes the intended transactions in sequence and by application of any conditional logic.

Basic Payment Interaction

With the required configuration for the merchant in place, online payments can now be processed.

The basic interaction between merchant, consumer, and Hellgate follows are general interaction pattern. This allows to streamline integrations and keep the complication low.

In a payment situation where the customer is present in the checkout, the payment processing on Hellgate always follows the same high-level interaction.

  1. The merchant creates a new payment on Hellgate
  2. For the consumer interaction a session-id is then provided
  3. Which is used to initialise the payment experience in a browser
  4. The consumer enters the payment method details
  5. Hellgate processes the payment according to the flow
  6. Redirects the consumer and allows the merchant to present the payment status
  7. The merchant server is kept up to date with notifications

Payment Use-Cases

To further cater for canonical situations in the payment industry, Hellgate has packaged-up these behaviours into defined use-cases.

Guest Payments

This is the simplest use case that Hellgate supports. In the case of a guest payment, the system collects all the data required for processing, such that no pre-existing customer data is required.

Creating the payment

The first step is to create a payment on Hellgate. The following example gives you a minimal example for a 47.11 EUR payment using a payment method type card.

curl --request POST \
--url https://api.hellgate.dev/payments \
--header 'X-API-Key: topsecret' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"amount": 4711,
"confirm": true,
"currency_code": "EUR",
"payment_method_types": [
"card"
]
}
'

When you created the payment with this setup, Hellgate will process it as a guest payment and will not store a payment method on file for later use.

The payment method type selector allows you to specify which payment method options will be available for the consumer and as such will influence the payment experience in the browser.

Payment result

After successful processing of the payment, the data will contain the payment method details. The following example shows a selection of attributes of the payment in that state:

{
"id": "afd954ee-a997-44a6-914d-cbb1bef0a248",
"amount": 4711,
"currency_code": "EUR",
"payment_method": {
"type": "card",
"card": {
"masked_number": "424242XXXXXX4242",
"expiry_year": 2030,
"expiry_month": 10,
"cardholder_name": "John Holder"
}
},
"use_case": "guest_payment"
}

A payment method was added to the payment data which shows you want instrument was actually used for the payment.

Storing the payment method after guest payment

If you want to achieve that the consumer pays as a guest and the payment method is then stored for later use, you can achieve this via the attribute store_payment_method_for when requesting the payment. You have to store it for a respective use-case (in this example Credentials on File - COF):

curl --request POST \
--url https://api.hellgate.dev/payments \
--header 'X-API-Key: topsecret' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"amount": 4711,
"confirm": true,
"currency_code": "EUR",
"payment_method_types": [
"card"
],
"store_payment_method_for": {
"use_case": "cof_payments"
}
}
'

The main difference will be that the payment method data will now hold an id property, such that you can later refer to it:

{
"id": "afd954ee-a997-44a6-914d-cbb1bef0a248",
"amount": 4711,
"currency_code": "EUR",
"payment_method": {
"id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc",
"type": "card",
"card": {
"cardholder_name": "John Holder",
"expiry_month": 10,
"expiry_year": 2030,
"masked_number": "424242XXXXXX4242"
}
},
"use_case": "guest_payment"
}

Credentials on File Payments

In situations where the consumer has consented to the storage of the payment method, the processing can be made easier and more convenient, by making use of this data.

info

Be aware that this use-case still requires to have the consumer present in the payment session. This is needed as for example authentication requirements have to be passed on and the consumer might have to input further data.

The big difference to the guest payments is, that you can now inject the payment method the moment you create the payment itself:

curl --request POST \
--url https://api.hellgate.dev/payments \
--header 'X-API-Key: topsecret' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"amount": 4711,
"confirm": true,
"currency_code": "EUR",
"payment_method_id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc"
}
'
info

Obviously it does not make sense to specify the allowed range of payment method types and the storage requirements. Both attributes will be removed (and thus ignored) from the payment when you send the request.

The resulting payment object will hold the expanded payment method details, like in the previous example:

{
"id": "afd954ee-a997-44a6-914d-cbb1bef0a248",
"amount": 4711,
"currency_code": "EUR",
"payment_method": {
"id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc",
"type": "card",
"card": {
"cardholder_name": "John Holder",
"expiry_month": 10,
"expiry_year": 2030,
"masked_number": "424242XXXXXX4242"
}
},
"use_case": "cof_payment"
}

First Payments

First payments are made to start a sequence of later payments (i.e. merchant initiated transactions). In the first payment the consumer needs to be present and as such gives consent to the later payments, which might be initiated by the merchant directly.

Starting from scratch

In case you don't have the payment method for the planned first payment on file, you can start basically with the guest checkout setup, but add different use-case this time. It depends if you want to use the payment method for regular recurring_payments or unscheduled_payments.

Additionally to the storage indicator, a customer_id and a mandate_reference text must be included:

curl --request POST \
--url https://api.hellgate.dev/payments \
--header 'X-API-Key: topsecret' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"amount": 4711,
"confirm": true,
"currency_code": "EUR",
"customer_id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"payment_method_types": [
"card"
],
"store_payment_method_for": {
"use_case": "recurring_payments",
"mandate_reference": "Monthly subscription"
}
}
'
note

Not all processors support the subtile difference between the recurring and unscheduled payments. In case the processor does not support explicit unscheduled payments, Hellgate will default to recurring payments instead.

In contrast to the guest payment example with the storage instruction for credentials on file, this time Hellgate generates mandate linked to this first payment after successful authorisation.

Mandates are Hellgate's terminology for credentials on file, which have been consented by the consumer for later merchant initiated payments.

So following the card payment instrument example from above, a NPR Mandate is created (NPR = network payment reference):

{
"id": "afd954ee-a997-44a6-914d-cbb1bef0a248",
"amount": 4711,
"currency_code": "EUR",
"customer": {
"id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"name": "John H. Holder"
},
"payment_method": {
"id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc",
"type": "npr_mandate",
"npr_mandate": {
"accepted_on": "",
"card": {
"cardholder_name": "John Holder",
"expiry_month": 10,
"expiry_year": 2030,
"masked_number": "424242XXXXXX4242"
},
"customer_id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"reference": "Monthly subscription",
"type": "recurring_payments"
}
},
"use_case": "first_payment"
}

Using credentials on file for a first payment

A first payment can also be bootstrapped with existing credentials on file. The slight difference is again the presence of the payment_method_id in the request:

curl --request POST \
--url https://api.hellgate.dev/payments \
--header 'X-API-Key: topsecret' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"amount": 4711,
"confirm": true,
"currency_code": "EUR",
"customer_id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"payment_method_id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc",
"store_payment_method_for": {
"use_case": "recurring_payments",
"mandate_reference": "Monthly subscription"
}
}
'

The presence of both the payment_method_id and the storage instruction, will create a new payment method on file, which is again a NPR Mandate in this example:

{
"id": "afd954ee-a997-44a6-914d-cbb1bef0a248",
"amount": 4711,
"currency_code": "EUR",
"customer": {
"id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"name": "John H. Holder"
},
"payment_method": {
"id": "4cd1f7ca-9654-41c3-9679-a97af1b882b8",
"type": "npr_mandate",
"npr_mandate": {
"accepted_on": "",
"card": {
"cardholder_name": "John Holder",
"expiry_month": 10,
"expiry_year": 2030,
"masked_number": "424242XXXXXX4242"
},
"customer_id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"reference": "Monthly subscription",
"type": "recurring_payments"
}
},
"use_case": "first_payment"
}

Recurring & Unscheduled Payments

note

Not all processors support the subtile difference between the recurring and unscheduled payments. In case the processor does not support explicit unscheduled payments, Hellgate will default to recurring payments instead.

Recurring payments are made at a defined regular interval with fixed or varying amount to cater for products and services. Recurring payments require a first payment to start the sequence.

With unscheduled payments, the merchant can initiate payments at non-fixed schedule using stored credentials. Typical situations are top-ups of a consumer account, when its balance drops beyond a certain threshold. Unscheduled payments also require a first payment.

Both payment types are not requiring the consumer to be present and represent merchant initiated payments.

The actual payment request is pretty straight forward, as only the payment_method_id of the mandate needs to be used (example given is an recurring payment):

curl --request POST \
--url https://api.hellgate.dev/payments \
--header 'X-API-Key: topsecret' \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '
{
"amount": 4711,
"confirm": true,
"currency_code": "EUR",
"payment_method_id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc"
}
'

The resulting payment after authorisation looks identical to the example above:

{
"id": "afd954ee-a997-44a6-914d-cbb1bef0a248",
"amount": 4711,
"currency_code": "EUR",
"customer": {
"id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"name": "John H. Holder"
},
"payment_method": {
"id": "2b4a46c9-a422-495b-8ed1-37daa7e9b2fc",
"type": "npr_mandate",
"npr_mandate": {
"accepted_on": "",
"card": {
"cardholder_name": "John Holder",
"expiry_month": 10,
"expiry_year": 2030,
"masked_number": "424242XXXXXX4242"
},
"customer_id": "416975fc-1137-4a02-91b8-a92f27a2c654",
"reference": "Monthly subscription",
"type": "recurring_payments"
}
},
"use_case": "recurring_payment"
}

Note that the customer of the mandate is automatically associated with the payment.