How does it work?
In the following document we will provide some example flows for a generic Payment Provider, called provider
.
Provider specific edge cases are covered in more detail in the following pages, this is more of a generic overview of
the Payment Gateway Manager and how to interact with it.
The Payment Gateway Manager interfaces aim to be agnostic to the payment provider used. Some providers may require additional fields, in which case they will be wrapped in a single, optional object field.
Core Concepts
Identifiers
- PaymentId: unique identifier of the payment provided by the
provider
- ShopTransactionId: unique identifier of the payment on the user's system
- SubscriptionToken: unique identifier of the subscription provided by the
provider
Amount and Currency
The amount
is expressed as an integer in order to avoid precision loss.
Together with the currency
value (ISO 4217) the correct float value can be computed.
Only "EUR" currency is supported at this moment
Payment
POST /{provider}/{payment-method}/pay
Perform a payment on the provider
with the payment-method
chosen.
Request
{
"amount": 500, // the amount to be paid
"currency": "EUR", // currency used for the payment
"shopTransactionId": "123456789", // the unique id of your transaction
"successRedirectUrl": "http://example.com/ok", // the URL to be redirected to if payment succeeds (optional)
"failureRedirectUrl": "http://example.com/ko", // the URL to be redirected to if payment fails (optional)
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
For more information about the content of the providerData
object, read the page related to the chosen provider.
Response
{
"result": "OK", // transaction result
"resultDescription": "Transaction Completed", // human readable transaction result (varies with the provider)
"paymentId": "payment-123456789", // payment transaction id as returned by the provider
"redirectToUrl": "https://provider-redirect-url.com", // redirect web page
"redirectToUrlMobile": "provider-app://redirect?token=example" // redirect iOS url-scheme, used to open the provider's app in iOS devices
}
The result field can have the following values:
- OK: the transaction has been performed successfully on the
provider
; - KO: the transaction has been rejected by the
provider
; - PENDING: the transaction is pending; an asynchronous notification will arrive from the
provider
with the information about the status of the transaction; - REDIRECT_TO_URL: the transaction is pending and needs further actions by the user in order to be completed; in this case at least one of the following fields is available:
- redirectToUrl: redirect to a web page
- redirectToUrlMobile: redirect iOS url-scheme, used to open the provider's app in iOS devices
Refund
POST /{provider}/refund
Perform a refund for a transaction on the provider
.
Request
{
"amount": 500,
"currency": "EUR",
"paymentId": "123456789",
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
Response
{
"result": "OK"
}
The result field can have the following values:
- OK: the refund has been performed successfully on the
provider
; - KO: the refund has been rejected by the
provider
; - PENDING: the refund is pending; an asynchronous notification will arrive from the
provider
with the information about the status of the transaction;
Subscriptions
The Payment Gateway Manager can interact with the provider
in order to manage subscriptions, that are recurrent payments.
A recurrent payment is a payment strategy that splits a whole payment across multiple installments, whose only the first one requires an interaction with the client (its authorization). An example of such payment strategy is paying monthly for a season ticket that covers one year.
Using an enabled provider, a client executes an initial payment where they also authorize the underlying system to perform future payments on their behalf, using the same details of the initial payment. This grant is defined through a token generated by the payments provider once the initial payment is successfully completed and returned to the payment system.
The following actions are available:
- schedule: the
provider
will automatically handle new recurring payments and send a notification when the status of a subscription changes - manually:
- start: create a new subscription on the
provider
- pay: perform a new payment related to an already created subscription on the
provider
- start: create a new subscription on the
- update: update information related to the subscription
- get status: get the subscription status
- expire: expire a subscription
An object subscriptionInfo
needs to be included in the request in order to specify information about the subscription.
{
"subscriptionInfo": {
"token": "0987654321", // unique id of the subscription
"interval": "DAY", // time unit
"intervalCount": 1, // frequency of the subscription
"expiresAfter": 1 // maximum number of payments for the subscription (optional)
}
}
The following values are accepted for the field interval:
- DAY
- MONTH
Each provider can accept only some interval values
On the response a SubscriptionToken is returned, that is the identifier to use in order to perform action on the correct subscription.
Schedule
POST /{provider}/{payment-method}/subscription/schedule
Create a new subscription managed entirely by the provider
.
The provider
will notify with a callback every change on the subscription.
Request
{
"amount": 200, // the amount to be paid at each recurrent payment
"currency": "EUR", // currency to use
"shopTransactionId": "1234567890", // the unique id of your transaction
"subscriptionInfo": {
"interval": "DAY", // time unit
"intervalCount": 1, // frequency of the subscription
"expiresAfter": 1 // maximum number of payments for the subscription (optional)
},
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
Possible values of subscrptionInfo.interval
are:
- DAY
- WEEK
- MONTH
- YEAR
Response
{
"result": "OK",
"resultDescription": "Payment Authorised",
"paymentId": "1234567890", // the unique id of the transaction for the specific provider
"subscriptionToken": "0987654321", // the unique id of the subscription
"metadata": {...} // object with provider-specific data (optional, varies with the provider)
}
Start
POST /{provider}/{payment-method}/subscription/start
Create a new subscription on the provider
.
Request
{
"amount": 200, // the amount to be paid at each recurrent payment
"currency": "EUR", // currency to use
"shopTransactionId": "1234567890", // the unique id of your transaction
"subscriptionInfo": {
"interval": "DAY", // time unit
"intervalCount": 1, // frequency of the subscription
"expiresAfter": 1 // maximum number of payments for the subscription (optional)
},
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
Response
{
"result": "OK",
"resultDescription": "Payment Authorised",
"paymentId": "1234567890",
"subscriptionToken": "0987654321",
"metadata": {...} // object with provider-specific data (optional, varies with the provider)
}
Pay
POST /{provider}/{payment-method}/subscription/pay
Create a new payment related to a subscription on the provider
.
Request
{
"amount": 200, // the amount to be paid at each recurrent payment
"currency": "EUR", // currency to use
"shopTransactionId": "1234567890", // the unique id of your transaction
"subscriptionInfo": {
"token": "0987654321" // the unique id of subscription
},
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
Response
{
"result": "OK",
"resultDescription": "Payment Authorised",
"paymentId": "1234567890",
"subscriptionToken": "0987654321",
"metadata": {...} // object with provider-specific data (optional, varies with the provider)
}
Update
POST /{provider}/subscription/update/{subscriptionToken}
Update subscription information.
Request
{
"amount": 200, // the amount to be paid at each recurrent payment
"currency": "EUR", // currency to use
"shopTransactionId": "1234567890", // the unique id of your transaction
"subscriptionInfo": {
"interval": "DAY", // time unit
"intervalCount": 1, // frequency of the subscription
"expiresAfter": 1 // the unique id of subscription
},
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
Response
{
"result": "OK",
"resultDescription": "Successful transaction",
"subscriptionToken": "0987654321"
}
Get Status
GET /{provider}/subscription/status/{subscriptionToken}
Get the subscription status. Available status are:
PENDING
: first payment to be executedACTIVE
: last payment executedPAST_DUE
: last payment failedEXPIRED
: the subscription has reached the expiration dateCANCELED
: the subscription has been manually canceledUNKNOWN
: the subscription status is unknown
The actual available status depend on the provider. It is always a subset of the list above. For more information visit the provider dedicated documentation page.
Response
{
"status": "ACTIVE",
"subscriptionToken": "098764321",
"providerName": "stripe",
"metadata": {...}
}
Expire
DELETE /{provider}/subscription/expire/{subscriptionToken}
Expire the subscription on the provider
.
Pay By Link
The Payment Gateway Manager is also able to handle the Pay By Link scenario, it requests the link to the provider and returns it. The user can simply click on the link and will be redirected to the provider specific payment page, with all the payment methods enabled through the dashboard of that provider. At the end of the process the PGM will receive a callback that notifies about the payment result.
POST /{provider}/pay-by-link
Request
{
"amount": 500, // the amount to be paid
"currency": "EUR", // currency used for the payment
"shopTransactionId": "123456789", // the unique id of your transaction
"successRedirectUrl": "http://example.com/ok", // the URL to be redirected to if payment succeeds (optional)
"failureRedirectUrl": "http://example.com/ko", // the URL to be redirected to if payment fails (optional)
"providerData": {...} // the object with provider-specific data (optional, varies with the provider)
}
Response
{
"resultCode": "OK", // transaction result
"resultDescription": "Transaction Completed", // human readable transaction result (varies with the provider)
"paymentId": "payment-123456789", // payment transaction id as returned by the provider (optional)
"link": "https://provider-redirect-url.com", // the created link
}
The result field can have the following values:
- OK: the link has been created successfully by the
provider
; - KO: the link has not been created by the
provider
;
Payment Status
The payment status is available through many endpoints with the following format:
{
"status": "ACCEPTED",
"paymentId": "1234567890",
"shopTransactionId": "0987654321",
"providerName": "PROVIDER_NAME",
"paymentMethod": "PAYMENT_METHOD",
"action": "PAYMENT",
"metadata": {...}
}
The result field can have the following values:
- ACCEPTED: the transaction has been performed successfully on the
provider
; - FAILED: the transaction has been rejected by the
provider
; - PENDING: the transaction is pending;
The action field can have the following values:
- PAYMENT: the status refers to a payment;
- REFUND: the status refers to a refund;
The metadata field is optional and can contain additional information.
Status
GET /{provider}/status?paymentId=0987654321
Retrieve payment status.
Check
GET /{provider}/check?paymentId=0987654321
The Payment Gateway Manager sends a callback with the status of the payment to an external service, as specified by the
PAYMENT_CALLBACK_URL
environment variable.
More details on how to configure the callback are available on the dedicated section.
M2M Callback Transaction Verification
GET /{provider}/callback
POST /{provider}/callback
When the transaction result is known by the generic-provider
, the latter may notify the Payment Gateway Manager.
This call will contain information allowing to identify the transaction.
The Payment Gateway Manager can use this information to check the transaction status, depending on the provider.
Once the check has been performed, the Payment Gateway Manager can notify the result to an external service, as specified by the
PAYMENT_CALLBACK_URL
environment variable.
The notification include the payment status as described above.
Utility
The Payment Gateway Manager exposes utility APIs for some providers. These APIs abstract the boundary operations and allow the developer to focus on the payment process itself, rather than the configuration processes. Check the provider page in order to find which utility APIs are available.
External Integration
The Payment Gateway Manager supports payment through custom external integrations. In this way, new payment methods can be integrated independently and the functionality of the Payment Gateway Manager can be extended with custom integrations. API calls to these endpoints will be redirected to external microservices where payment management logic will be implemented. Below, the interface exposed:
- Payment Request:
POST /{external}/pay
- Refund Request:
POST /{external}/refund
- Manage Subscriptions:
- Schedule a new Subscription:
POST /{external}/subscription/schedule
- Start manually a new Subscription:
POST /{external}/subscription/start
- Perform manually a payment related to a Subscription:
POST /{external}/subscription/pay
- Update a Subscription:
POST /{external}/subscription/update/{subscriptionToken}
- Expire a Subscription:
DELETE /{external}/subscription/expire/{subscriptionToken}
- Schedule a new Subscription:
- Get status of a Transaction:
POST /{external}/status
- M2M Callback Transaction Status Verification:
GET /{external}/callback
- On-Demand Transaction Status Verification:
GET /{external}/check
More details about custom external integrations are available on the dedicated section.
Payment Saga APIs - Flow Manager Integration
The Payment Gateway Manager is able to communicate with Flow Manager service via REST APIs by sending events and exposing a dedicated interface:
- Payment Request:
POST /saga/pay
- Refund Request:
POST /saga/refund
- Manage Subscriptions:
- Schedule a new Subscription:
POST /saga/subscription/schedule
- Start manually a new Subscription:
POST /saga/subscription/start
- Perform manually a payment related to a Subscription:
POST /saga/subscription/pay
- Schedule a new Subscription:
More details about flow manager integrations are available on the dedicated section.
Documentation
You can view the Swagger compatible OpenAPI documentation by calling the /documentation
endpoint.
You can also use /documentation/openapi.json
as the documentation endpoint in the microservice configuration to add it
to the API Portal.
Metrics
The Payment Gateway Manager expose the following metrics:
http_payment_created_total
: total number of http calls to payment provider to create the paymenthttp_payment_authorized_total
: total number of http calls to payment provider to authorize the paymenthttp_payment_expired_total
: total number of http calls to payment provider to expire the paymenthttp_payment_refunded_total
: total number of http calls to payment provider to refund the paymenthttp_payment_link_created_total
: total number of http calls to payment provider to create payment linkhttp_payment_status_total
: total number of http calls to payment provider to get payment statushttp_subscription_authorized_total
: total number of http calls to payment provider to authorize a subscriptionhttp_subscription_created_total
: total number of http calls to payment provider to create a subscriptionhttp_subscription_update_total
: total number of http calls to payment provider to update a subscriptionhttp_callback_total
: total number of http calls callback received by the payment providershttp_utils_total
: total number of http to payment providers for utils functionalitieshttp_flow_manager_service_total
: total number of http calls to flow manager servicehttp_crud_service_total
: total number of http calls to crud servicehttp_subscription_handler_total
: total number of http calls to subscription handler service