Webhooks
The payment adapter should be able to handle data which is required by the Accesstype. The payment gateway webhooks will be handled by the Accesstype only but it will provide the data which will be helpful for fulfiiling some business logic of the Accesstype. The webhooks will have some of the mandatory methods which will be called by the Accesstype and it should return the expected response to the Accesstype.
This methods will be called by the Accesstype when the webhooks will be receive to the Accesstype.
We will call the webhooks class of the payment adapter where we will pass the credentials details and environment of the account. Therefore, payment adapter will always have the payment gateway credentials and other details in every method.
We have already created one payment adapter gem for razorpay payment gateway. In which the accesstype is initializing the razorpay webhooks as below,
credentials = {'app_key'=>'<APP_KEY_OF_RAZORPAY>', 'secret'=> '<SECRET_KEY_OF_RAZORPAY>', 'enabled'=>true, 'webhook_secret'=>'12345a'}
accesstype_razorpay = AccesstypeRazorpay::Webhooks.new(credentials: credentials, environment: '<live or sandbox>')
In the same above manner webhooks should be done for other payment gateways. After initialization of the webhook class, accesstype will call different instance methods like webhook_request_authorized?
, webhook_event_type_mapping
, webhook_event_details
and etc.
webhook_request_authorized?
This method will be used by the accestype to verify whether the received webhook request is authorited or not. Different payment gateways has vary ways to identify whether request is authorized or not based on the some secret. For instance, for razorpay payment gateway, you would receive X-Razorpay-Signature
parameter in the request header and need to verify based on webhook_secret
which we will send in credentials argument.
Arguments
We would send the request object which contains all the parameters provided by the payment gateway. You may need to checkout the sample payload given by the payment gateway for particular payment gateway. For razorpay, you can checkout here
Response
The accesstype will expect boolean type of response for this method, It can be either true or false. If the accesstype will receive false it won’t proceed with that webhook. If you don’t know how to authorized webhook, you can directly return true
so the accesstype will understand all the requests are authorized.
webhook_event_type_mapping
This is the mandatory method which decides which accesstype job should be called for which webhook event. This method will be used for mapping between the webhook event type and the accesstype job which will be called for handling that webhook event. It won’t expect any arguments. Below is the sample code for this method, which was written for accesstype razorpay adapter.
{
'payment.authorized' => 'one_time_subscription_charged',
'subscription.charged' => 'recurring_subscription_charged',
'subscription.halted' => 'recurring_subscription_cancelled',
'subscription.cancelled' => 'recurring_subscription_cancelled'
}
It is the combination of key and value where keys will be the event name from the payment gateway and value will be the class name for handling that webhook event. This keys must need to match with the event name of webhook for payment gateway and it should also match with webhook_event_details[:event]
. As of now the accesstype has below jobs which is primarily required for handling different webhhoks,
-
one_time_subscription_charged
- This will be used when one time payment is completed and we have received the confirmation from the payment gateway. If the payment was completed and subscription wasn’t created due to some reason, this job will take care to create the subscription based on the webhook event details. -
recurring_subscription_charged
- This job will be used when we receive the payment for recurring subscription. Generally, we will receive the webhook event when payment is deducted for recurring subscription. This job will assure to extend theend_timestamp
of the subscription based on the request parameters. -
recurring_subscription_cancelled
- This job will be used when we receive subscription cancellation event from the payment gateway. This job will be assure to cancel the subscription from the accesstype.
webhook_event_details
This method will be used by the accesstype to fetch particular data from the webhook event. This is the most important method as the accesstype will rely on this method for fetching the data which will be insert in the accesstype database.
Arguments
We would send the request object which contains all the parameters provided by the payment gateway. You may need to checkout the sample payload given by the payment gateway for particular payment gateway. For razorpay, you can checkout here
Response
The accesstype will expect a hash from this method which contains attempt_token, amount_cents, amount_currency, status, etc. Below are the attributes from sample of hash,
- attempt_token String(required)
- It is the accesstype attempt token send while requesting for the payment. You need to fetch this value from the payload, it would be name as `attemptToken`
- event String(required)
- name of the webhook event
- amount_currency String(required)
- currency received from the payment gateway for transaction
- amount_cents String(required)
- amount cents received from the payment gateway for transaction
- status String(required)
- you must be received different status of payment for different webhook like `charged`, `authorised`, `cancelled` etc.
- external_payment_id String(required)
- id recieved from the payment gateway, generally a payment token
- external_subscription_id String(required)
- id recieved for the subscription
- email String(optional)
- email received from the payload, you can use `nil` if it is not received from the payload
- contact String(optional)
- contact received from the payload, you can use `nil` if it is not received from the payload
- payment_gateway_fee_cents String(optional)
- payment gateway fee received from the payload, you can use `nil` if it is not received from the payload
- payment_gateway_fee_currency String(optional)
- payment gateway fee currency received from the payload, you can use `nil` if it is not received from the payload
before_exit_on_subscription_absence
When the payment deducted event is received by the webhook but the accesstype doesn’t have any subscription related for that event. The accesstype will call this method which will cancel the subscritpion on the payment gatway as well as refund the full amount to the user.
Arguments
We would send the request object which contains all the parameters provided by the payment gateway. You may need to checkout the sample payload given by the payment gateway for particular payment gateway. For razorpay, you can checkout here
Response
The accestype won’t expect any response from the payment adapter gem. Payment adapter gem has to make sure the subscription is cancelled on the payment gateway in case of recurring payment and amount has been refunded to the user. If the payment adapter get exception while cancellation or refund process it should be logged as error.
renewal
This method will be used for fetching the renewal details for the recurring subscription. When the payment has been made for the recurring subscription, this method will call the get_subscription
Api and send the response of the API to the accesstype. The main attribute in the response is end_timestamp
. The accesstype will update the end_timestamp of subscription same as received by the payment gateway.
Arguments
We would send the request object which contains all the parameters provided by the payment gateway. You may need to checkout the sample payload given by the payment gateway for particular payment gateway. For razorpay, you can checkout here
Response
The Accesstype will expect a success response as below,
#<AccesstypeRazorpay::PaymentResult:0x00007fa33e48afb0 @payment_type="razorpay_recurring", @success=true, @payload=nil, @end_timestamp= '2020-11-23 11:42:14', @payment_gateway_fee=1047, @payment_token=nil, @status="captured", @amount_currency=nil, @amount_cents=nil, @international=nil, @skip_invoice=nil, @metadata=nil, @external_payment_id=nil, @external_payment_id= 'sub2421842167842168', @payment_gateway_fee_currency=nil, @external_refund_id=nil>