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.

Alternative Payment Methods

Rules for handling payments are only applied to card payments. PaymentsOS will always direct transactions using alternative (non-card) payment methods 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, choose Decision Engine from the left menu and select a business unit. 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.

Notes

  • You can create up to 100 payment processing rules (the total number of routing, block and instant retry rules combined).
  • You should not implement instant retry rules for transaction flows that involve 3DS authentication. 3DS is a step introduced to authenticate the user, so it should occur only once.

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.

Routing Transactions to a Provider Supporting External 3DS

If you use an external MPI (merchant plug-in) to authorize a card using 3D Secure, then you can pass the 3DS data returned from the MPI in the three_d_secure_attributes.external object of a Create Authorization or Create Charge request. However, not all the providers you transact against may be able to receive this data. You should thus configure a route rule to direct the request to a provider that can process data received from an external 3DS service.

Finding a provider that supports external 3DS

See Finding a Provider to find a provider that supports external 3DS (choose a payment method type of Cards and apply an additional filter by choosing a 3DS External version from the Features list). Make sure to review the provider's setup procedures in the relevant provider topic, since some additional configuration may be required.

To route a transaction to a provider that supports data from an external 3DS service, you must first pass a custom key-value pair in the additional_details object of a Create Authorization or Create Charge request. Note that you can choose any key-value pair of your liking (in the example below, we pass a key of external_mpi_3ds_results with a value of true):

{
  "payment_method": {
    ...
  },
  ...
  "three_d_secure_attributes": {
    "external": {
      "three_d_secure_version": "1.0.0",
      "cavv": "Unqiue CAVV",
      "eci_flag": "ECI associated with the transaction.",
      "encoding": "BASE64",
      "xid": "transaction ID"
    },
    "additional_details": {
      "external_mpi_3ds_results": "true"
    }
  }
}

You can now create a Payments Routing rule based on Transaction Additional Details. Set the key to your custom key (from_external_mpi in the example above) and the String value to your custom value (true in the example above).

Routing Transactions to the Next Provider if the Target Provider is not Available

If PaymentsOS detects that the target provider is not available, then you can instruct the Decision Engine to skip the current rule and move on to the next rule in line. To do so, simply switch the Skip to next rule if target provider is down toggle.

Disclaimer

Under the hood, PaymentsOS invokes the Retrieve Health Status API request to determine the availability status of your providers. The status is a representation of the availability of your providers and is calculated by PaymentsOS based on various parameters, such as the frequency of transaction requests invoked through PaymentsOS and the number of provider responses received within a given time frame. The status therefore only reflects the availability status of your providers within the scope of PaymentsOS and is not indicative of their availability outside that scope.

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 ""