Skip to main content

Webhooks (Draft)

Using the webhook, merchant application can get real time updates on the payment status and payment-method related events.

Payments

Supported Events

Event TypeDescriptionApplicable payment method types
PAYMENT_SUCCEEDEDEmitted when payment is captured and is successful.CARD, BANK_ACCOUNT
PAYMENT_SUCCEDEDEmitted when payment is captured and is successful. **Will be deprecated** CARD, BANK_ACCOUNT
PAYMENT_FAILEDEmitted when a payment fails.CARD, BANK_ACCOUNT
PAYMENT_ACCEPTEDEmitted when a payment is submitted successfully and is being processed.CARD, BANK_ACCOUNT
PAYMENT_AUTHORIZEDEmitted when a payment is AUTHORIZED. Authorized payment should be captured later using capture endpoint to complete the payment.CARD
PAYMENT_CANCELEDEmitted when a payment is canceled.CARD, BANK_ACCOUNT

Event Structure

FieldTypeValid valuesDescription
nameEnumPAYMENT_SUCCEEDED, PAYMENT_FAILED, PAYMENT_ACCEPTED, PAYMENT_AUTHORIZED, PAYMENT_CANCELEDEvent name
payloadPayloadEvent Payload

Payload Structure

FieldTypeValid valuesDescription
amountlong50 - 99999999Amount (in cents) requested for payment
authorizedAmountlong50 - 99999999(PRE_AUTH) Maximum amount approved for capture (in cents); Starting R27, pre-authorization and partial-authorization, should infer this field to consider authorized amount; Prior to R27, infer amount field;
capturedAmountlong50 - 99999999(SALE) Amount(in cents) immediately settled. (PRE_AUTH) Amount(in cents) successfully captured.
partialAuthorizationbooleantrue/false(PRE_AUTH) Indicates whether a partial authorization was requested.
descriptionstringMax length 50Payment Description
iduuidvalid uuid4Payment Identifier
merchantIduuidvalid uuid4Merchant Identifier
merchantTransactionIdstringMax length 50MerchantTransactionId sent by the merchant with original payment request
paymentDateUtcdateDate in ISO string formatPayment completed datetime
paymentMethodPaymentMethodPaymentmethod Description
errorErrorError Information
consentConsentConsent required for bank account payments

Error Structure

FieldTypeValid valuesDescription
codestringMax length 50Short code for error
descriptionstringMax length 255Error description
errorDetailsErrorDetailsError details

Error Details Structure

FieldTypeValid valuesDescription
codestringMax length 100code for error
messagestringMax length 255Error description
declineCodestringMax length 100Decline Code
networkAdviceCodestringMax length 100Network Advice Code
networkDeclineCodestringMax length 100Network Decline Code

Important Note

In the event that payment is captured and succeeded, we will be publishing two events: PAYMENT_SUCCEDED and PAYMENT_SUCCEEDED.

PAYMENT_SUCCEDED will be deprecated by 06/15/2024 and only PAYMENT_SUCCEEDED will be published going forward.

Sample Event

Events will be sent in JSON format.

card object under paymentMethod is deprecated in favor of paymentMethodDetails. Please refer PaymentMethod for more details.

{
"name": "PAYMENT_SUCCEEDED"
"payload": {
"amount": 1500,
"description": "Payment Description",
"id": "6ab9bf74-03e0-4f47-bd70-bf57b103a5fd",
"merchantId": "44387763-4eeb-4592-a564-b10aadee95be",
"merchantTransactionId": "e31de58d-cb20-40ff-ad58-b99d500z0001",
"paymentDateUtc": "2011-10-05T14:48:00.000Z",
"paymentMethod": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"card": {
"last4": "string",
"type": "CARD",
"status": "ACTIVE",
"cardBrand": "VISA",
"expiryYear": 0,
"nameOnCard": "string",
"expiryMonth": 0,
"zipCode": "string",
"manufacturerCard": false
},
"paymentMethodDetails": {
"last4": "string",
"type": "CARD",
"status": "ACTIVE",
"cardBrand": "VISA",
"expiryYear": 0,
"nameOnCard": "string",
"expiryMonth": 0,
"zipCode": "string",
"manufacturerCard": false
},
"default": true,
"paymentMethodType": "CARD",
"nickname": "string"
},
"error": {
"code": "card_declined",
"message": "Your card has insufficient funds.",
"declineCode": "generic_decline",
"errorDetails": {
"code": "no_account",
"message": "The customer's bank account could not be located.",
"declineCode": "generic_decline",
"networkDeclineCode": "51",
"networkAdviceCode":"02"
}
}
}
}

Payment-method

Supported Events

  • PAYMENT_METHOD_CREATED - Emitted when a payment method is created.
  • PAYMENT_METHOD_UPDATED - Emitted when a payment method is updated.
  • PAYMENT_METHOD_DELETED - Emitted when a payment method is deleted.
  • PAYMENT_METHOD_REPLACED - Emitted when a payment method is replaced, find more details here.

Event Structure

FieldTypeValid valuesDescription
nameEnumPAYMENT_METHOD_CREATED, PAYMENT_METHOD_UPDATED, PAYMENT_METHOD_DELETED, PAYMENT_METHOD_REPLACEDEvent name
payloadPayloadEvent Payload

Payload Structure

FieldTypeValid valuesDescription
paymentMethodPaymentMethodPaymentmethod Description
customerCustomerCustomer Description
agentAgentAgent Description
deletedPaymentMethodIdUUIDValid UUIDDeleted PaymentMethod Id, in PAYMENT_METHOD_REPLACED event

Customer Structure

FieldTypeValid valuesDescription
enterpriseIdstringMax lengthPayment method Id
hsiduuidvalid uuid4Healthsafe Identifier
metadatastringMax length 50Client provided additional metadata

Agent Structure

FieldTypeValid valuesDescription
firstNamestringMax length 50First name of Agent
lastNamestringMax length 50First name of Agent
userIdstringMax length 50MSId of Agent
isAccessVerifiedbooleantrue/falseIs access verified by merchant

Paymentmethod Structure

FieldTypeValid valuesDescription
iduuidvalid uuid4Payment method Id
cardCardCard Description when payment Method is of type CARD.
Deprecated in favour of paymentMethodDetails
nicknamestringMax length 50Payment method nickname
defaultbooleantrue/falsedetermines if the payment method is default for the customer
paymentMethodTypestringMax length 50Payment method type can be CARD or BANK_ACCOUNT
paymentMethodDetailsCard or ACHOne of Card or ACH

Card Structure

FieldTypeValid valuesDescription
nameOnCardstringMax length 50Name of the customer
cardBrandstringVISA, AMEX, DINERS, DISCOVER, JCB, MASTERCARD, UNIONPAY, UNKNOWNCard brand
expiryMonthlong01-12Month of expiration
expiryYearlongMax length 4Year of expiration
last4stringMax length 4Last four digits of the card
zipCodestringMax length 55 digit zipcode
statusstringACTIVE/EXPIREDStatus of the card
manufacturerCardbooleantrue/falseDetermines if the card is manufacturer card or not. Only Agents can flag certain cards as manufacturer cards. Cards flagged as manufacturer cards cannot be default card.

ACH Structure

FieldTypeValid valuesDescription
typestringBANK_ACCOUNTType of the PaymentMethod
accountHolderTypestringindividual or companyAccount holder type
accountTypestringchecking or savingsAccount Type
bankNamestringBank Name
last4stringLast 4 digits of bank account number
routingNumberstringRouting number of bank
nameOnAccountstringName on Account
statusenumACTIVE and INVALIDATEDBank Account Status
FieldTypeValid valuesDescription
merchantConsentIdstringValid UUIDConsent Id
merchantConsentTextstringConsent text
collectionTimestampstringTimestamp of when the consent was collected
collectionDetailsConsentCollectionDetailsDetails about how consent was collected
FieldTypeValid valuesDescription
typeenumWEB, TEL, PPDConsent type
webConsentCollectionWebDetails of consent collected through the website
telConsentCollectionTelDetails of consent collected through the telephone
FieldTypeValid valuesDescription
ipAddressstringValid IP addressIP address from which the consent is collected
userAgentstringAgent involved in the consent collection
FieldTypeValid valuesDescription
phoneNumberPhoneNumberValid country code and phone numberPhone number from which the consent is collected

Phone Number Structure

FieldTypeValid valuesDescription
countryCodestringValid country codeCountry code
numberstringValid phone numberPhone number

Sample Event

Events will be sent in JSON format.

CARD Payment Method

card object under paymentMethod is deprecated in favor of paymentMethodDetails. Please refer PaymentMethod for more details.

{
"name": "PAYMENT_METHOD_CREATED | PAYMENT_METHOD_UPDATED | PAYMENT_METHOD_DELETED | PAYMENT_METHOD_REPLACED",
"payload": {
"paymentMethod": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"card": {
"last4": "string",
"type" : "CARD",
"status": "ACTIVE",
"cardBrand": "VISA",
"expiryYear": 0,
"nameOnCard": "string",
"expiryMonth": 0,
"zipCode": "string",
"manufacturerCard": false
},
"paymentMethodDetails": {
"last4": "string",
"type" : "CARD",
"status": "ACTIVE",
"cardBrand": "VISA",
"expiryYear": 0,
"nameOnCard": "string",
"expiryMonth": 0,
"zipCode": "string",
"manufacturerCard": false
},
"default": true,
"paymentMethodType": "CARD",
"nickname": "string"
},
"customer": {
"enterpriseId": "enterprise id",
"hsid": "hsid",
"dateOfBirth": "dob",
"metadata": {
"patientId": "rx-patient-id"
}
},
"agent": {
"firstName": "First Name",
"lastName": "Last Name",
"userId": "msId",
"isAccessVerified": true
},
"deletedPaymentMethodId": "597f6eca-6276-4993-bfeb-53cbbbba6f12"
}
}
Payment with BANK ACCOUNT
{
"name": "PAYMENT_SUCCEDED",
"payload": {
"amount": 5000,
"capturedAmount": 5000,
"partialAuthorization": false,
"description": "Test Payment from Postman_003",
"id": "27f986f9-8440-4d30-8816-b3faf82dfd2e",
"merchantId": "44387763-4eeb-4592-a564-b10aadee95be",
"merchantTransactionId": "a812eb9d-9726-4764-b30a-06c234a75fa1",
"paymentDateUtc": "2024-05-06T12:26:27.192037",
"consent": {
"merchantConsentText": "some text",
"collectionTimestamp": "1054684654",
"collectionDetails": {
"type": "TEL",
"tel": {
"inboundPhoneNumber": {
"countryCode": "1",
"number": "1234567890"
}
}
}
},
"paymentMethod": {
"paymentMethodType": "BANK_ACCOUNT",
"nickname": "Nickname test",
"paymentMethodDetails": {
"type": "BANK_ACCOUNT",
"accountHolderType": "individual",
"accountType": "checking",
"bankName": "STRIPE TEST BANK",
"last4": "6789",
"routingNumber": "110000000",
"nameOnAccount": "Name on account test",
"status": "ACTIVE"
},
"default": true
}
}
}
Partial authorization
{
"name": "PAYMENT_AUTHORIZED",
"payload": {
"amount": 5000,
"capturedAmount": 0,
"authorizedAmount": 3500,
"partialAuthorization": true,
"description": "Test Payment from Postman_16",
"id": "2b12ce09-73eb-43c3-b39b-89419f319746",
"merchantId": "44387763-4eeb-4592-a564-b10aadee95be",
"merchantTransactionId": "100ee626-0795-4b5e-b0d9-c543868207b1",
"paymentDateUtc": "2024-05-06T12:43:19.550101",
"paymentMethod": {
"card": {
"cardBrand": "VISA",
"expiryMonth": 5,
"expiryYear": 2055,
"last4": "0014",
"status": "ACTIVE",
"manufacturerCard": false
},
"paymentMethodType": "CARD",
"paymentMethodDetails": {
"type": "CARD",
"cardBrand": "VISA",
"expiryMonth": 5,
"expiryYear": 2055,
"last4": "0014",
"status": "ACTIVE",
"manufacturerCard": false
},
"default": false
}
}
}

REFUND

Refund events are sent when a refund is processed. Refunds can be processed for both CARD and BANK_ACCOUNT payment methods. There are two types of refunds that can be processed i.e., linked and unlinked refunds.

  • Linked refunds are processed against a payment and unlinked refunds are processed without a payment.
  • In case of unlinked refunds i.e., credit / cashback, payment method id is needed to process the refund.

Supported Events

Event TypeDescriptionApplicable payment method types
REFUND_SUCCESSEmitted when refund is successful.CARD, BANK_ACCOUNT
REFUND_FAILEDEmitted when a refund fails.CARD, BANK_ACCOUNT
REFUND_PENDINGEmitted when a refund status is pending.CARD, BANK_ACCOUNT

Event Structure

FieldTypeValid valuesDescription
nameEnumREFUND_SUCCESS, REFUND_FAILED, REFUND_PENDINGEvent name
payloadPayloadEvent Payload

Payload Structure

FieldTypeValid valuesDescription
amountlong50 - 99999999Refund amount in United States Cents
reasonStringMax length 50Refund reason
refundIduuidvalid uuid4Refund Identifier
PaymentPaymentPayment Details
merchantTransactionIdStringMax length 50MerchantTransactionId sent by the merchant with original refund request
merchantIduuidvalid uuid4Merchant Identifier
metadataStringMax length 50Client provided additional metadate
paymentMethodPaymentMethodPaymentmethod Description
errorErrorError Information
statusStringCOMPLETED and FAILEDRefund Status

Error Structure

FieldTypeValid valuesDescription
codestringMax length 50Short code for error
descriptionstringMax length 255Error description
errorDetailsErrorDetailsError details

Error Details Structure

FieldTypeValid valuesDescription
codestringMax length 100code for error
messagestringMax length 255Error description
declineCodestringMax length 100Decline Code
networkAdviceCodestringMax length 100Network Advice Code
networkDeclineCodestringMax length 100Network Decline Code

Sample Event

Events will be sent in JSON format.

{
"name": "REFUND_SUCCESS | REFUND_FAILED | REFUND_PENDING",
"payload": {
"amount": 100,
"reason": "DUPLICATE",
"status": "COMPLETED",
"payment": {
"id": "d3398a06-e038-4aaa-9a6f-08e6884b6aa9",
"amount": 900000,
"merchantId": "b955db5e-aef2-47de-bbb9-c80b9cc16e8f",
"description": "UI widget payment",
"capturedAmount": 900000,
"partialAuthorization": false,
"merchantTransactionId": "68da00a3-d96c-4731-ad9c-f7b4f005b04c"
},
"refundId": "242ecd9b-333a-4537-ba95-bea1de6ce973",
"merchantId": "b955db5e-aef2-47de-bbb9-c80b9cc16e8f",
"paymentMethod": {
"card": {
"last4": "4444",
"status": "ACTIVE",
"zipCode": "94043",
"cardBrand": "MASTERCARD",
"expiryYear": 2026,
"nameOnCard": "Card Holder Name",
"expiryMonth": 12,
"manufacturerCard": false
},
"default": false,
"nickname": "",
"paymentMethodType": "CARD",
"paymentMethodDetails": {
"type": "CARD",
"last4": "4444",
"status": "ACTIVE",
"zipCode": "94043",
"cardBrand": "MASTERCARD",
"expiryYear": 2026,
"nameOnCard": "Card Holder Name",
"expiryMonth": 12,
"manufacturerCard": false
}
},
"merchantTransactionId": "b6d52a1f-b4e7-4de7-85de-9bd5032d7643"
},
"error": {
"code": "VENDOR_ERROR",
"message": "Cannot issue refund on expired or cancelled card",
"declineCode": "generic_decline",
"errorDetails": null
}
}

Merchant Webhook Implemetation Requirements

  1. Merchant should expose a https endpoint that should be reachable in public internet.
  2. Merchant should validate the request using the Authorization token that comes as part of the request header. The authorization token is a JWT token. A public key for validating the token will be provided as a part of Merchant onboarding by CCG team.

Validating the JWT Authorization Token

The JWT token will be sent as Authorization Header in the HTTPS request.

# Header
Authorization:Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ7bWVyY2hhbnRJZH0iLCJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTUxNjI0OTAyMn0.188mvtjbW1xf6fCFNun0ZjlreckxFnUEEGZO-rvvdp3II-70C-M_W7QP6Dm7B57qnZJq6lPWxCjJnbF3hkTtAg

The JWT token should be validated for

  1. Expiry
  2. Signature

The JWT tokens will be signed using ES256 (Eliptical Curve Cryptography with 256 bit hashing) algorithm.

Failures and Retries

Retry attempts will happen when we received a failure from the webhook endpoint. The below table has the list of errors which are not retriable.

EndpointNot Retriable Errorcodes
Webhook400 Bad Request, 413 Request Entity Too Large, 403 Forbidden, 404 Not Found, 401 Unauthorized

If the error returned from webhook is not among the above list we will perform retry. We wait 30 seconds for a response after delivering a message. After 30 seconds, if the endpoint hasn’t responded, the message is queued for retry. We are using an exponential backoff retry policy for event delivery. we perform 5 attempts in 50 mins with exponential backoff.