> For the complete documentation index, see [llms.txt](https://docs.coda.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coda.co/codapay/direct-api-integration/direct-api-integration-for-cards/get-notified-of-a-charge-status-change.md).

# Get notified of a charge status change

Coda will issue server-to-server notifications to keep you updated on the payment status. Depending on the transaction's progress, you may receive one or several notifications, each reflecting the current state of the payment.

### Pre-requisite

* The transaction completion notification URL is configured

### **Payment notifications**

Notification to be received for Authorize, Captured, Succeed, Failed payment statuses

#### **Current Environment Availability**

| Environment | Is Available? |
| ----------- | ------------- |
| Sandbox     | Yes           |
| Production  | Yes           |

#### Notification Parameters

| Parameter Name | Data Type   | Description                                 |
| -------------- | ----------- | ------------------------------------------- |
| id             | String      | identifier of notification event            |
| data           | JSON Object | data that contain charge information Object |

#### Headers

| Key            | Description                                                                                 |
| -------------- | ------------------------------------------------------------------------------------------- |
| x-signature    | The signature created by requestTime and requestBody, encrypted by using HMAC512 algorithm. |
| x-request-time | The epoch timestamp when the request was created.                                           |

**Steps:**

1. Append the values listed below as a string as follows: *"{requestTime}.{requestBody}"*\
   *Example:*

```java
// Java
RequestTime = 1700486578888
RequestBody = {"type":"charge.status.succeeded","data":{"id":"evt_sg18c678ba5af0019"}}
String message =
"1700486578888.{"type":"charge.status.succeeded","data":{"id":"evt_sg18c678ba5af0019"}}"
```

2. Calculate the HMAC-SHA512 hash of the string using your signing secret as the key. The signing secret is a pre-shared key configured for your webhook endpoint. The HMAC-SHA512 algorithm will return a byte array value.

   *Example:*

```java
// Java
SigningSecret = "BbCVjTu59yVUMMon8mgN9C37piCGfijN"
```

3. Convert the byte array value to a hexadecimal string. The result will be like:

   "a0c2d905877e9282a3954743f918f98f991c144020c535458c84767b6e146cf8cad4433accc2047258f6d5c4be07264596cfc58cfeea9e8551090f26e828e6bd"

**Verifying the Signature**

1. Extract the X-Request-Time and X-Signature headers from the webhook request
2. Get the raw request body as a string (before any parsing)
3. Generate the expected signature following Steps 1-3 above
4. Compare the generated signature with the X-Signature header value using a constant-time comparison
5. Verify that the X-Request-Time is within an acceptable time window (e.g., within last 5 minutes) to prevent replay attacks

#### **data**

Data contains an object similar to the charge object which you get from [Get Charge Data](https://docs.google.com/document/d/1XA9FRZ0ndMm8HHiTmweSKgM_wahoA8wTURBjPEup0yQ/edit#heading=h.g2d2u869o4a3) endpoint response.

Below are the fields you need to focus on:

| Parameter Name     | Data Type | Description                                                                                                                                                                                                     |
| ------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                 | String    | Identifier of charge                                                                                                                                                                                            |
| created\_at        | Instant   | Timestamp of when the charge was created                                                                                                                                                                        |
| status\_code       | String    | Current State of the payment. See the full list of possible statuses [here](https://app.gitbook.com/o/6r6nr9F9QL33fFAul7Gs/s/l56STCN5yoV1K1MhVEvU/~/changes/496/codapay/references/direct-api-charge-statuses). |
| error\_code        | String    | Error code of the failed charge. See the full list of possible error codes [here](/codapay/references/direct-api-charge-error-codes.md).                                                                        |
| error\_description | String    | The error code description of a failed charge. See full list of possible error code description [here](/codapay/references/direct-api-charge-error-codes.md).                                                   |
| partner\_reference | String    | ID provided by the partner for the payment                                                                                                                                                                      |

### **Capture Approval Notification**

#### Current Environment Availability

| Environment | Is Available? |
| ----------- | ------------- |
| Sandbox     | Yes           |
| Production  | Yes           |

Coda will issue a server-to-server REST connection to ask you what action coda should perform after successful payment authorization.

#### **Capture Parameters**

The contract of the Capture Request is similar to [<mark style="color:purple;">Payment notifications</mark>](#payment-notifications), except it is not wrapped to a data object.&#x20;

Below are the fields you need to focus on:

| Parameter Name     | Data Type | Description                                                                                                                                                                            |
| ------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id                 | String    | Identifier of charge                                                                                                                                                                   |
| created\_at        | Instant   | Timestamp of when the charge was created                                                                                                                                               |
| status\_code       | String    | <p>Current State of the payment. See the full list of possible statuses <a href="/pages/JCtdZOqFvdf9jEyCUBP0">here</a>.</p><p>You should expect waiting\_capture\_approval status.</p> |
| partner\_reference | String    | ID provided by the partner for the payment                                                                                                                                             |

#### **How to activate**

You should pass the pre\_capture\_ack\_url parameter to the [Submit Charge request](/codapay/direct-api-integration/direct-api-integration-for-cards/submit-a-charge.md)<mark style="color:purple;">.</mark> Otherwise, all authorized charges will be automatically captured.

Once the issuing bank has authorized the payment, if we received pre\_capture\_ack\_url, then we will send the capture request notification as REST Request.&#x20;

The request from coda should contain a charge object with status\_code: waiting\_capture\_approval.

This will indicate that the authorization was completed and Coda is waiting for your acknowledgement.

#### **What you should response**

You can optionally choose to authorize or decline a transaction after the user has confirmed the payment and issuing bank has authorized it.

If you want to have the option to decide if you want to&#x20;

(a) proceed with capture or&#x20;

(b) to cancel an authorized charge

You will need to reply to the notification call to tell us whether the capture for that charge can proceed. The response should be as follows (see samples [here](https://docs.google.com/document/d/1XA9FRZ0ndMm8HHiTmweSKgM_wahoA8wTURBjPEup0yQ/edit#heading=h.6h96ppka7kqi)):

| Parameter Name  | Data Type | Description                                                                                                   |
| --------------- | --------- | ------------------------------------------------------------------------------------------------------------- |
| charge\_id      | String    | Unique identifier for the charge                                                                              |
| perform\_action | String    | Indicates whether the capture request is approved or declined by sending confirm\_capture or decline\_capture |

#### **Retry policy**

**Current Environment Availability**

| Environment | Is available |
| ----------- | ------------ |
| Sandbox     | Coming soon  |
| Production  | Coming soon  |

Please note that, if we don’t receive a response to the capture notification, we will resend the capture request 3 times, a few minutes apart. If the retries don’t work, we will assume that the merchant has declined the charge and we will not proceed with the capture of the funds.

For all notifications, If our POST request does not receive a 2XX response, we will employ an exponential backoff strategy and retry the request up to three times.

<br>

Retry Schedule After Initial Failure:&#x20;

* First Retry: 1 Minute
* Second Retry: 5 Minutes
* Third Retry: 30 Minutes

\
After 3 failed retries, we will not process the event further. For the capture request notification, after 3 failed retries, we will not process the event further and we will assume that the capture request has been declined. This means that the charge will be canceled and we will issue a status change notification with payment status as canceled.\
\
\ <br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.coda.co/codapay/direct-api-integration/direct-api-integration-for-cards/get-notified-of-a-charge-status-change.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
