Currently, there is a growing need among companies to offer the possibility of making payments directly through their web portal to their users. Without this possibility, the acquisition of products or services offered by said company is cumbersome, slow and unusable by a large part of the market; which is summarized in a significant loss of potential buyers. Now, providing this possibility not only requires proper implementation but also requires having certain security protocols to ensure that neither the company nor the consumer will be victims of the large number of frauds that occur on the web daily, among other problems. that can be presented.

In order to facilitate the online payment process as well as guarantee security and trust for both the company and the consumer, there are payment gateways; whose purpose is to take care of all the processes related to money. Simply, the consumer pays through said payment gateway, it informs the company of the status of the transaction made and the company delivers the product or service to the consumer depending on that status. If there is a problem with the money, the payment gateway is responsible; which simplifies the internal processes of the company and gives peace of mind to both, the company and to the consumer by having an external agent in charge of the transparency of the transaction.

One of the payment gateways is PayU, widely used in Latin America. Like all payment gateways, it has its advantages and disadvantages; Its use depends on the needs of your business to receive payments via the web as well as the ease of integrating said gateway with your platform. In the case of PayU, they have support for the REST API which facilitates its integration with most platforms. Precisely, in this post I will briefly discuss how to use this support to implement one of the most attractive PayU functionalities: Recurring Payments.

READ
Dockerizing Django Apps

In short, a recurring payment is a subscription that will automatically charge the credit card associated with said subscription periodically; this period is configurable when the subscription is created or edited. To integrate this functionality with our site, the following should be considered.

Connection with PayU’s API

In order to connect to your PayU account through the API, you must send a basic authorization in the “Authorization” header, which consists of a username, in this case, the API Login of your account, and a password, which corresponds to the API Key of your account. With this information in the header, all transactions must be made with PayU or else you will receive an authentication error code.

Plan creation

After having the authentication process, you have to create the plans that your company will offer. For this, a POST request must be made to “/payments-api/rest/v4.9/plans” For example:

{
  "accountId": "512321",
  "planCode": "sample-plan-code-001",
  "description": "Sample Plan 001",
  "interval": "MONTH",
  "intervalCount": "1",
  "maxPaymentsAllowed": "12",
  "paymentAttemptsDelay": "1",
  "additionalValues": [
    {
      "name": "PLAN_VALUE",
      "value": "20000",
      "currency": "COP"
    }
  ]
}

In this case, you are creating a recurring plan that will charge $ 20,000 monthly, which is associated with account 512321 and whose code is “sample-plan-code-001”. This plan will be charged for 12 months and will then be canceled (maxPaymentsAllowed) and payment will only be attempted once before canceling the subscription (paymentAttemptsDelay). It is not necessary for this entry to describe the rest of the information, but it is easily deductible when viewing the JSON.

If the creation was successful, you will receive a similar response to the one shown below:

{
  "id": "b3d406d0-abd4-473c-a557-25aa81ff9032",
  "planCode": "sample-plan-code-001",
  "description": "Sample Plan 001",
  "accountId": "512321",
  "intervalCount": 1,
  "interval": "MONTH",
  "maxPaymentsAllowed": 12,
  "maxPaymentAttempts": 0,
  "paymentAttemptsDelay": 1,
  "maxPendingPayments": 0,
  "trialDays": 0,
  "additionalValues": [
    {
      "name": "PLAN_VALUE",
      "value": 20000,
      "currency": "COP"
    }
  ]
}

Otherwise, you will receive a message with the error description. For example:

{
  "type": "BAD_REQUEST",
  "description": "El plan con el código [sample-plan-code-210] ya existe para el comercio [508029]"
}

It should be noted that this process needs to be executed only once per plan created.

READ
Working with nested forms with Django

Plan subscription

Once you have created at least one recurring plan, you can now subscribe users to start automatic debit as soon as possible. For this, it is required to send a JSON with the customer and credit card information to be used through a POST request to “/rest/v4.9/subscriptions/”. For example:

{
  "immediatePayment": true,
  "installments": 10,
  "customer": {
    "fullName": "Jhon Doe",
    "email": "[email protected]example.org",
    "creditCards": [
      {
        "name": "Jhon Doe",
        "document": "0000000001",
        "number": "4242424242424242",
        "expMonth": 1,
        "expYear": 2022,
        "type": "VISA"
      }
    ]
  },
  "plan": {
    "planCode": "sample-plan-code-001"
  }
}

As in the case of the creation of the recurring plan, you will receive a message with the description of the subscription in case of success and a message with the description of the error otherwise. In either case, the user will receive an email from PayU with the details of the transaction made.

On the other hand, it is worth noting that PayU generates objects for each credit card and each customer created in its database. For this reason, the ID of these objects can be sent directly when creating the plan subscription instead of sending all the information again, as in the previous example. These IDs come within the response obtained in case you have made a successful subscription to be saved in your database in case your system requires it.

Invoices

The final step is to check the collection of the transaction to validate that the money was indeed debited. To obtain the billing information, a GET request must be made to “/rest/v4.9/recurringBill” with any of the following parameters:

1. “?customerId={customerId}”, returns all invoices for the required PayU custumer.
2. “?subscriptionId={subscriptionId}”, returns all invoices for the required subscription.
3. “?customerId={customerId}&dateBegin={dateBegin}&dateFinal={dateFinal}”, returns all invoices for the required costumer in the given date range. It is worth noting that it requires both the dateBegin parameter and the dateFinal; if these are not supplied, the PayU system returns an error.

READ
Beeware: Write Apps with Python!

In any of these cases, you will receive a settlement with all the invoices related to the request:

{
  "recurringBillList": [
    {
      "id": "cc522b0e-af0b-4ece-978d-f5c5632caa52",
      "orderId": 71516840,
      "subscriptionId": "6dtg51j09cr",
      "state": "PAID",
      "amount": 10000,
      "currency": "COP",
      "dateCharge": 1391490000000
    },
    {
      "id": "56f0f5ca-cf29-437e-8920-7bc35578a39f",
      "subscriptionId": "6dtf4q8v451",
      "state": "CANCELLED",
      "amount": 10000,
      "currency": "COP",
      "dateCharge": 1392786000000
    }
  ]
}

With this information, it is easy to determine the status of customer payments. This step is the one that, in my opinion, has the most failures from the PayU system. The problem is that its filter is very limited so it can be cumbersome to determine the payment of an invoice under specific conditions. Still, for a normal use case, this part of the PayU system is effective.

Final considerations

As you can see, integrating your system with PayU recurring payments is quite simple since, when using the REST API as a communication method, it uses the JSON format, to receive and deliver the information. This means that implementing the integration in any language, from a server or client application, does not require further consideration or complicated implementations. Although it has some details that could be better (for example, credit card errors are not organized and the delivery format is not the same if there is an error than if there are several errors) PayU offers a simple and safe method that is worth taking advantage of to provide this type of service to your company’s clients.

Finally, it is worth clarifying that this post is just a mouthful of the integration process with PayU and that it is necessary to read the official documentation in order to carry out an adequate implementation and that considers factors such as errors, response times, among others.


Comments