Step 2.1 - Subscriptions Callbacks

As subscriptions are a recurring process, there can be various subscription activity: users cancel their subscriptions, or want to upgrade their subscription by choosing one-off. For each of these events - and more - you'll likely want to take steps on your site. Callbacks provide a reliable way to be notified of payment failures on subscription. A payment failure can be a temporary problem - as the card issues might have declined the charge - or it could indicate that there are other issues on the customers side.  

This is why it is important to understand all of MobilePay callbacks, as they walk through accepting and processing payment failure notifications, so you can intuitively take action, and for example email your customer, if something should happen.

 
Step 2.1. payment_status_callback_url

You set the payment_status_callback_url yourself by making a call to our API. Go to -> APIs -> Subscriptions and find the  patch method to set the payment_status_callback_url
We cannot send callbacks to you, unless you have set the payment_status_callback. The payment_status_callback_url does not need to be whitelisted at MobilePay side. Please configure the payment_status_callback_url before you start to send payment requests. Note that callbacks can only be delivered using ports 80 and 443.

Example of body
  [
  {
   "value": "http://example.com",
   "path": "/payment_status_callback_url",
   "op": "replace",
   "from": "http://example.com"
  } 
 ] 

Once the Payment Status Callback url is set, you are ready to receive callbacks! Note: If you are an integrator helping a Merchant with their integration, MobilePay sends the callback to integrators Payment Status Callback url.

In case of downtime, we recommend that you always implement the GET calls below, as a fallback.

Useful GET calls

There is no admin panel to check request, but you can use the following API calls:

Agreement
  • GET /api/providers/{providerId}/agreements - Get a list of agreements
  • GET /api/providers/{providerId}/agreements/{agreementId} - Get agreements details

Payment 

  • GET /api/providers/{providerId}/agreements/{agreementId}/paymentrequests - Get a list of payments in a given agreement
  • GET /api/providers/{providerId}/agreements/{agreementId}/paymentrequests/{paymentId} - Get single payment details  
  • GET /api/providers/{providerId}/agreements/{agreementId}/oneoffpayments - Get all OneOff payments of a single agreement
  • GET /api/providers/{providerId}/agreements/{agreementId}/oneoffpayments/{paymentId} - Get single OneOff payment details

Refunds

  • GET /api/providers/{providerId}/agreements/{agreementId}/payments/{paymentId}/refunds - Get a list of refunds issued for particular payment
How do callbacks work?


You get notified about the agreement and payment status via REST callbacks. You have updated information about your customer agreement and subscriptions.
We are sending callbacks in two ways:

  1. A batch that runs every 2 mins. It contains Subscription payments with status: Declined/Rejected/Failed/Executed/OneOff_Expired. So in theory, there is a possible delay of 2 mins..
  2. Right after the user made an action. It contains OneOff_Reserved/OneOff_Rejected.

Every two minutes we take up to 1000 events (notifications about payment state), group them by merchant and make the calls. Therefore, as for merchant you should get up to 1 call every two minutes. We will post the integrator or merchant a callback, and expect a HTTP 2xx response. If not we will retry 8 times.


What should I do if my system was not able to receive or correctly process the callback?

If erroneous call-backs are discovered within 30 days, contact MobilePay Developer Support.

Please configure the payment_status_callback_url before you start to send payment requests.

External_id  

When utilizing callbacks, it is important that you evaluate your usage of external_id, as it will be included in the request body of the refund callback, as well in the reference number and bank statement. The merchant is responsible for setting the external_id. If the merchant is using instant transfer, then the reference number will be the external_id for recurring payments and one-off payments. Merchant can set Instant transfers themsleves in the MobilePay Portal. Read more about reconciling subscriptions payments here

"External_id" for agreements

  • It is possible to update the external_id. But the parameter is meant as a unique identifier, chosen by the merchant, which shouldn’t change. On our side we have the "agreement_id, which never changes regardless of what happens to the agreement. That is the counterpart to the external_id on your side. It should stay the same, so we can trace the full history of the agreement. 
  • The customer can see the external_id in the app.
  • Our recommendation is, that the external_id is the users agreement id or reference with you. So that it does not seem confusing for the user. And if they have more than one Subscriptions agreement with you, they should be able to see which Subscriptions agreement is connected to which merchant agreement.
  • The external_id is included in the request body of the success and cancel callback. 
  • Maximum length is 64 characters

external_id for payments 

  • The same goes for the payments, the external_id will be included in the request body of the payment callback
  • The customer can also see the payment external_id in the app. 
  • Our recommendation is that the external_id is unique for each payment.
  • Maximum length is 30 characters (this will soon be larger).

 

external_id for refunds

external_id for one-off's

parameter type Required Description
one_off_payment.external_id string(30) required One-Off payment identifier on the merchant's side. This will be included in the request body of the payment callback. 

 

Updating the external_id

  • This is done using the PATCH /api/merchants/me/agreements/{agreementId} endpoint.
REST Callback Retries

In case the REST callback failed, 8 retries will be made using the exponential back-off algorithm where N - next retry time, c - retry attempt number, R - second retry time in seconds (1st retry is an exception and is done after 5 seconds):

Retry

  • 1st retry – 5 seconds. 
  • 2nd retry – 10 minutes after 1st retry.
  • 3rd retry – 30 minutes after 2nd retry.
  • 4th retry – 1h 10 minutes after 3rd retry.
  • 5th retry – 2h 30 minutes after 4th retry.
  • 6th retry – 5h 10 minutes after 5th retry.
  • 7th retry – 10h 30 minutes after 6th retry.
  • 8th retry – 21h 10 minutes after 7th retry.
  • The callback service will try to deliver its message through our retry mechanism - we make up to 8 retries. 
  • When a callback goes through whole cycle of multiple retries, it ends up in MobilePay Error Queue. You do not access to this Queue. 
  • You should use our API to retrieve a current status of the entity. 
Agreements
 
New Status Condition URL Callback status Callback status_text Callback status_code
Accepted  User swiped to accept the Agreement  success-callback Active    0 
Rejected User tapped the Cancel button during the sign-up. cancel-callback Rejected  Agreement rejected by user 40000 
Expired User did not do anything during the agreement timeout period.  cancel-callback Expired  Pending agreement expired 40001 
Canceled User canceled an Active agreement cancel-callback Canceled  Agreement canceled by user 40002 
Canceled Merchant canceled an Active agreement cancel-callback Canceled  Agreement canceled by merchant 40003 
Canceled System canceled an Active agreement because user was Deleted cancel-callback Canceled  Agreement canceled by system. 40004 

Note: When an user cancels an Active agreement, you might want to use your own business logic to manage the payment lifecycle from now on. There might be a possibility that the customer would like to return to your service later on.  

retention_period_hours

Merchant can set for how long agreement can’t be cancelled by the user, after the user accepted the agreement, for up to 24 hours. To set this, the merchant needs to use retention_period_hoursThis is an advantage in relation to street sales and when/if merchants offer cheaper prices, if the customer establishes a subscription agreement with the merchant. Before retention period has passed, then the cusomer will not be able to cancel the agreement 

Find the whole documentation about agreements on GitHub

Subscriptions payments  
New Status  Condition When to expect Callback status Callback status_text Callback status_code
Executed The payment was successfully executed on the due-date After 03:15 in the morning of the due-date Executed    0 
Failed Payment failed to execute during the due-date. After 23:59 of the due-date Failed    50000 
Rejected User rejected the Pending payment in MobilePay Any time during the 1 day period when user is presented with the Pending payment in the MobilePay activity list. Rejected  Rejected by user. 50001 
Declined Merchant declined the Pending payment via the API Any time during the 1 day period when user is presented with the Pending payment in the MobilePay activity list. Declined  Declined by merchant. 50002 
Declined Agreement is not in Active state. Right after the payment request was received. Declined  Declined by system: Agreement is not “Active” state. 50003 
Declined Another payment is already scheduled on that day for the user. Right after the payment request was received. Declined  Declined by system: Another payment is already due. 50004 
Declined When the Agreement was canceled by merchant or by system Any time during the 1 day period when user is presented with the Pending payment in the MobilePay activity list. Declined  Declined by system: Agreement was canceled. 50005 
Rejected When the Agreement was canceled by user Any time during the 1 day period when user is presented with the Pending payment in the MobilePay activity list. Declined  Declined by system: Agreement was canceled. 50005 
Declined A catch-all error code when payment was declined by core system. Right after the payment request was received. Declined  Declined by system. 50006 
Declined Declined due to user status. Right after the payment request was received. Declined  Declined due to user status. 50009 
Declined When the Agreement does not exist Right after the payment request was received. Declined  Agreement does not exist. 50010 
Declined When the due date before rule is violated Right after the payment request was received. Declined  Due date of the payment must be at least 1 day in the future. 50011 
Declined When the due date ahead rule is violated Right after the payment request was received. Declined  Due date must be no more than 32 days in the future. 50012 

We send callbacks instantly and if first delivery fails we wait and send them again, next time we wait a bit longer and send them again. That’s where delay could build up.

Keep on track with payment problems 

1. Handling payments that require additonal action

Sometimes, when a customer’s subscription comes due, the payment fails. The customer might have canceled their card, the card might have expired, or the payment might be declined by the card issuer for some other reason. Suddenly, life is less good.

Fortunately, MobilePay Subscriptions helps the merchant in this situation. We send push notifications to customers smartphone. When a payment requires additional steps, such as customer authentication or exchange of card, the customer will be notified via push notifications. Upon receiving the push notification, the customer is pushed to complete the required action. For details on which push notifications, the customer might receive, read more here.

However, if you have specific design requirements for customizing emails’ trigger conditions, content, or other details, you are more than welcome to do that on your side. It could be beneficial to make customized system that automatically notifies your customers when a subscription payment fails. You know your customer, and you can further target the message.

2. grace_period_days

When a payment failed, we will automatically retry, if you have configured grace_period_days in the payment request. grace_period_days lets merchants to configure how many days MobilePay will try to complete unsuccessful payment. It is optional to use grace_period_days. We can try for maximum 3 days. On due date we process the payments starting from 02:00. If some payments weren't successfully completed, we will then try again approx. every 2 hours. When grace_period_days field is not set or is set to 1, we will keep retrying to complete the payment up until 23:59 of the same day. When grace_period_days is set to more than 1, we will be trying to complete the payment for specified number of days. The user will get at notification approx. at 08:30 that we at MobilePay cannot process the payment and that they can complete it manually (by swiping). Notification will be sent every day on the same time for the whole grace period if  grace_period_days is specified.

More information can be found here.

 

OneOff Payments 
 
New Status Condition When to expect Callback status Callback status_text Callback status_code
Reserved  The one-off payment was accepted by user and money is reserved for you on his card. You can now capture the money  After user accepts the requested one-off payment  Reserved  Payment succesfully reserved 0 
Rejected User rejected one-off payment request in MobilePay app. Right after user rejects one-off payment Rejected  Rejected by user 50001
Expired User did not do anything during the agreement timeout period.  1 day after you requested one-off payment Expired  Expired by system 50008 

Read more about one-off payments in our public GitHub documentation in the link below. 

You will get callbacks about the payment to your callback address. Moreover, you will get callbacks about the agreement to either success or failure url, that you have set upon agreement creation. However, you will not get callbacks for either, before their status changes. So you should expect a callback when the agreement is accepted / rejected / expired and a callback when the OneOff is either accepted/rejected/expired.

You can capture a payment only once for an order, and the payment can’t be more than the order’s authorized amount. This means that your customers can’t add to an existing order. If they want to add more products after an order has been placed, then they need to make a new order.

It is mandatory for the merchant to Capture or Cancel one-off payment if it was reserved on a customer account. It results in bad end-user experience, if the amount is reserved on the customer’s account for too long, without them receiving their product. It might also result in increased calls to support unit, which is to be avoided at all cost.

How are the payment batches?   
  • Batch details: a batch request contains of multiple API calls combined into one HTTP request. 
  • Requestpayment endpoint accepts an array of payment requests. Batch is more readily processed than single, individual calls, because single calls results in extra load. 
  • You can batch payment requests into payloads of max 2.000 payments. We allow merchants to bundle multiple payment requests into a single http request.
  • You get an answer on the payments that are executed in the first batch and later in the day, in case there are more payments that are executed.  
Refunds
New Status Condition When to expect Callback status Callback status_text Callback status_code
Issued The Refund was successfully issued Right after the refund request was received Issued     
Declined If Payment is fully refunded. Right after the refund was requested  Decline  Payment is fully refunded. 60001 
Declined If the total sum of previous Refunds exceed the original payment amount.  Right after the refund was requested Declined  The total sum of previous Refunds cannot exceed the original payment amount. 60002 
Declined When Refund was declined by system Right after the refund was requested Declined  Payment was not found. 60003 
Declined When Refund was declined by system Right after the refund was requested Declined  Payment cannot be refunded. 60004 
Declined A catch-all error-code when Refund was declined by code system Right after the refund was requested Declined  Refund was declined by system 60005

Read more about refund here

From step 2.1 to 3

Once you have finished testing in sandbox and have understood the importance of Subscriptions callbacks, you have to go through a small verification process, to ensure that your system is ready for production.