Optimizing Payments

Note

The functionality outlined below is only supported with credit card payments.

Payment managers can optimize a payment flow by configuring a set of rules that determine how each payment is handled. PaymentsOS provides an extensive list of rule criteria to select from. Rules may, for instance, route payments to a specific provider depending on the currency in which the payment was made, direct payments to yet another provider based on the customer's card brand, block a payment based on the country where the card was issued, and so forth.

Untokenized Payments

Rules for handling payments are only applied to tokenized (card-based) payments. PaymentsOS will always direct untokenized payments to the default provider defined in your business unit configuration. If your default provider is not suited to handle the request, then you must create a separate business unit with a default provider dedicated to handle transactions that do not use cards.

To configure payment processing rules, login to the PaymentsOS Control Center and edit your business unit configuration. Then scroll down to Optimise your payment flow and choose a rule policy. A rule policy represents the type of rule you can configure:

  • Payments Routing: Allows you to configure rules that route payments to specific providers based on the conditions specified.

  • Block Payments: Allows you to configure rules that prevent unwanted transactions from reaching providers, blocking payments based on the conditions specified.

  • Instant Retry: Allows you to configure rules that reroute a payment to another provider, in the event that a provider receiving a transaction request failed to process the payment.

PaymentsOS combines the rules you configured to form a decision flow (you can configure one decision flow per business unit). Under the hood, PaymentsOS uses its Decision Engine to evaluate the rules in the decision flow and process each payment accordingly. This introduces some additional considerations that you need to be aware of.

Constructing a "One Size Fits All" Request Body

The outcome of a rule may result in a payment being routed to any of the providers configured to be used in the decision flow. When constructing a request body, you must thus ensure that you include all fields required by the providers to which a payment may be routed. This may seem like a daunting task, but do not despair! Hop over to our Bodybuilder, select the providers of your choice and generate a "one size fits all" request body with just a single click of the mouse.

Creating Policy Rules based on Custom Data

While PaymentsOS covers a range of rule conditions designed to meet the most common decision flow scenarios, you may also want to define rules based on information you provided to enrich your customers' transaction data. This is where rule conditions based on additional details come into play. It offers you the ability to create custom-fit decision rules, using virtually any type of data available to you.

Configuring Rules based on Additional Details

When adding a new rule to your rule policy, choose Add Condition > Additional Details.

If you are familiar with our APIs, you may recall that you can enrich transaction data by passing additional information in the additional_details object of some of our API requests. Here's an example of additional information passed in the request body of a Create Customer request.

...
{
  "customer_reference": "cust_john",
  "first_name": "John",
  "last_name": "Taylor",
  "email": "John.Taylor@gmail.com",
  "additional_details": {
    "user_status": "banned_user"
},
...

Notice the key (user_status) and value (banned_user) passed in the example above. Use these in the key and value fields respectively, when configuring your rule:

Additional Details Rules

When creating a condition using the custom data you provided, you can select from the following additional details:

Routing Transactions Coming from the Virtual Terminal

The Virtual Terminal allows you to initiate a payment on behalf of a customer and charge your customer on-the-fly.

Transactions coming from the Virtual Terminal are treated as any other transaction and may thus be routed to any of the providers defined in your business rules. However, some providers require customers to authenticate themselves, or require that you submit specific information (provider-specific data) for the transaction to go through. In this case, the Virtual Terminal will return a message indicating that the transaction could not be completed. You can prevent this from occurring, by creating a route rule that directs payments coming from the Virtual Terminal to a provider that does not require user authentication or provider-specific data.

To route transactions initiated from the Virtual Terminal, create a Payments Routing rule based on Transaction Additional Details. Set the key to vt and the String value to true.

Understanding the decision_engine_execution Resource

If policy rules have been configured, the response of a Create Authorization or Create Charge request will also include a decision_engine_execution object. This object contains information about the decision flow and the rules that were evaluated as payments pass through the flow:

{  
  ...
  "decision_engine_execution": {
    "id": "a66d524c-aca6-4218-9170-f7d2c2051d1e-462f-40b3-a1f3-ee4b768f338e",
    "created": "1533737775251",
    "flow_id": "8db806df-fd3f-42a4-a710-81f8a777df18",
    "status": "InProgress",
    "policy_results": [
      {
        "type": "BlockPolicy",
        "name": "my-block-policy",
        "execution_time": "2018-08-08T14:16:15.249Z",
        "result": "Hit"
      }
    ]
  }

Note

Refer to to the REST API Reference for an explanation of the fields in the decision_engine_execution object.

As each rule is evaluated, a corresponding policy result object is created in the policy_results array. This object summarizes the evaluation of the rule. The policy result object's type field indicates the policy to which the rule belongs. Notice that the type corresponds to the policy that can be selected when configuring a rule in the PaymentsOS Control Center. The only exception is the target_policy type. This type is created by the Decision Engine the moment the payment is passed on to a provider (the "target" of the rule).

The example below shows a policy_results array with result objects of multiple types.

"policy_results": [
      {
        "name": "My Block Policy Rule",
        "execution_time": "2018-08-14T08:09:07.525Z",
        "result": "Hit",
        "type": "BlockPolicy"
      },
      {
        "name": "My Route Policy",
        "execution_time": "2018-08-14T08:20:06.527Z",
        "result": "Hit",
        "provider_name": "CyberSource",
        "provider_configuration": "https://api.paymentsos.com/accounts/my_app_1534320543208/providers-configurations/eba3accc-0f82-48c2-9a3c-10de48a322bb",
        "transaction": "https://api.paymentsos.com/payments/e8847624-9b2e-4eb6-bc3c-33b946d48502/charges/63f56afb-b612-4bdf-8f87-638b56cfd5e1"
      },
      {
        "name": "TargetPolicy",
        "execution_time": "2018-08-14T08:21:00.522Z",
        "result": "Hit",
        "provider_name": "CyberSource",
        "provider_configuration": "https://api.paymentsos.com/accounts/my_app_1534320543208/providers-configurations/eba3accc-0f82-48c2-9a3c-10de48a322bb",
        "transaction": "https://api.paymentsos.com/payments/e8847624-9b2e-4eb6-bc3c-33b946d48502/charges/63f56afb-b612-4bdf-8f87-638b56cfd5e1"
      }
    ]

Interpreting the Request Status when a Block Rule is Applied

A block rule blocks payments based on the conditions specified. When a payment is blocked on an Authorization or Charge request, the request will return a result object that includes a status field with a value of cancelled and a category field with a value of blocked_by_decision_engine. Here's a sample result object returned by a Retrieve Authorization request:

...
 "result": {
        "status": "Cancelled",
        "category": "blocked_by_decision_engine",
        "description": "A Block Rule was applied to this transaction. You can view and modify your Block configuration in the Control Center."
    },
...

Interpreting the Request Status when an Instant Retry Rule is Applied

An instant retry rule instructs PaymentsOS to reroute a payment to another provider, in the event that a provider receiving a transaction request failed to process the payment. You should bear this in mind when checking the status of the transaction flow.

Instant Retry Rules with Synchronous Transaction Flows

In the case of a synchronous transaction flow, instant retry rules may result in a delay (of up to 60 seconds) in receiving a response with the status of the request. If you registered webhooks with a synchronous flow, you should also bear in mind that you will receive multiple webhook create events when instant retry rules are executed:

{
    "created": "2018-09-05T06:44:35.484Z",  // I tried with the first provider.
    "account_id": "961c2dee-d531-4b5f-8550-3de73570e982",
    "app_id": "com.zooz.docapp",
    "payment_id": "8d3f9e6a-d89b-48bd-9d68-07e1bb582687",
    "data": {
        "id": "557a4e32-d2e9-495a-9a0b-f2a18c39d91b",
        "created": "1536129864640",
        ...
    },
    "id": "8d3f9e6a-d89b-48bd-9d68-07e1bb582687-2018-09-05T06:44:35.484Z-83233f6e-767f-4f55-9d8f-448019e90fbf"
},
{
    "created": "2018-09-05T06:44:45.484Z", // I tried with a second provider, so here's another webhook event.
    "account_id": "961c2dee-d531-4b5f-8550-3de73570e982",
    "app_id": "com.zooz.docapp",
    "payment_id": "8d3f9e6a-d89b-48bd-9d68-07e1bb582687",
    "data": {
        "id": "557a4e32-d2e9-495a-9a0b-f2a18c39d91b",
        "created": "1536129864640",
        ...
    },
    "id": "9d3g9e6g-d99b-48be-9d68-17e1bc583686-2018-09-05T06:44:45.484Z-83233f6e-767f-4f55-9d8f-448019e90fbf"
}

Instant Retry Rules with Asynchronous Transaction Flows

If your flow is asynchronous, you're most likely using webhook events in order to be notified of a change in a request's status. Recall that the webhook body also returns the full transaction resource that initiated the event, including the status of the transaction. However, if the status of the transaction is Failed, you cannot assume that this is the final status since a retry rule may still be applied (in which case the transaction may succeed with the next provider in line).

Here's a sample webhook body. Notice that the status of Failed may not be final.

{
    "id": "13344450-77e9-45b6-9bbe-88fff8c451e5-2018-10-03T04:58:35.385Z-83233f6e-767f-4f55-9d8f-448019e90fbf",
    "created": "2018-10-03T04:58:35.385Z",
    "account_id": "961c3ded-d539-4b5f-8950-3de93570e988",
    "app_id": "com.zooz.docapp",
    "payment_id": "13344450-77e9-45b6-9bbe-88fff8c451e5",
    "data": {
        "id": "cb615c8f-319d-4349-a276-f4ecc7d770d3",
        "created": "1538542712789",
        "payment_method": {
            ...
            }
        },
        "result": {
            "status": "Failed" // Wait! An instant retry rule may be applied, so the transaction may still succeed. 
        },
        "provider_data": {
           ...
        },
        "amount": 4097
    }
}

So as a rule of thumb, if the status of the transaction resource is Failed, always verify that the status of the decision flow is Completed before checking the final status of the request itself. Remember that you can find the status in the decision_engine_execution object of an Authorization or Charge resource:

...
  "decision_engine_execution": {
    "id": "a66d524c-aca6-4218-9170-f7d2c2051d1e",
    "flow_id": "8db806df-fd3f-42a4-a710-81f8a777df18",
    "flow_owner_type": "Application",
    "policy_results": [
      {
        "type": "FallbackPolicy",
        "name": "my-fallback-policy",
        "execution_time": "2018-08-08T14:16:15.249Z",
        "result": "Hit"
      }
    ],
    "status": "Completed" // The Decision Engine completed its work. You can now safely rely on the status returned by the request itself.
  }

Note

If no decision_engine_execution resource has been created (which is the case if no business rules have been defined), then a status of Failed as returned in the webhook body is final.

results matching ""

    No results matching ""