# 2 - Notifications (IPN)

### **Étape 2 :** Gérer les notifications de paiement instantanées (IPN)

Une notification de paiement est envoyée après chaque paiement à une URL de rappel configurée soit dans votre tableau de bord, soit définie dans le lien de paiement.

### Demande de notification de paiement instantanée

**`POST`**  `callbackUrl`  **`InstantPayment Notification method`**

### **Response codes**

#### **Success**

| Code               | Reason                                     |
| ------------------ | ------------------------------------------ |
| `200 - Ok`         | Request was successful.                    |
| `204 - No Content` | Request was successful and has no content. |

#### &#x20;Error &#x20;

| Code                 | Reason                                                   |
| -------------------- | -------------------------------------------------------- |
| `400 - Bad Request`  | Request was successful.                                  |
| `401 - Unauthorized` | User must authenticate before making a request.          |
| `403 - Forbidden`    | Policy does not allow current user to do this operation. |

### **Request Parameters**

<table data-header-hidden data-full-width="false"><thead><tr><th width="281.4000244140625"></th><th width="111.60009765625"></th><th width="95.5999755859375"></th><th></th></tr></thead><tbody><tr><td><strong>Name</strong></td><td><strong>Location</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>id</code></td><td>body</td><td><code>string</code></td><td>The transaction's unique identifier.</td></tr><tr><td><code>payment</code></td><td>body</td><td><code>Payment</code></td><td>The transaction's related payment.</td></tr><tr><td><code>payment.id</code></td><td>body</td><td><code>string</code></td><td>The payment's unique identifier.</td></tr><tr><td><code>payment.type</code></td><td>body</td><td><code>enum</code></td><td>The payment's type. The avalaible<br>values are  <code>full</code> and <code>partial</code>.</td></tr><tr><td><code>payment.application</code></td><td>body</td><td><code>object</code></td><td>The payment's application<br>identifier.</td></tr><tr><td><code>payment.invoice</code></td><td>body</td><td><code>invoice</code></td><td>The payment's invoice.</td></tr><tr><td><code>payment.extras</code></td><td>body</td><td><code>object</code></td><td>The payment's invoice.</td></tr><tr><td><code>payment.totalAmountAlreadyPaid</code></td><td>body</td><td><code>float</code></td><td>The payment total amount already paid.</td></tr><tr><td><code>invoice</code></td><td>body</td><td><code>invoice</code></td><td>The information of the invoice paid.</td></tr><tr><td><code>invoice.id</code></td><td>body</td><td><code>string</code></td><td>The invoice's unique identifier.</td></tr><tr><td><code>invoice.customerId</code></td><td>body</td><td><code>string</code></td><td>The customer's unique identifier.</td></tr><tr><td><code>invoice.totalAmount.amount</code></td><td>body</td><td><code>float</code></td><td>The total amount paid for the<br>invoice.</td></tr><tr><td><code>invoice.totalAmount.currency</code></td><td>body</td><td><code>string</code></td><td>The currency of the total amount paid for the invoice. The currency must be in <a href="https://www.iso.org/fr/iso-4217-currency-codes.html">ISO 4217</a> format.</td></tr><tr><td><code>invoice.issuedAt</code></td><td>body</td><td><code>string</code></td><td>The date on which the invoice was issued. The date must be in <a href="https://www.iso.org/fr/iso-8601-date-and-time-format.html">ISO 8601</a> format.</td></tr><tr><td><code>invoice.dueDate</code></td><td>body</td><td><code>string</code></td><td>The date on which the invoice will be due. The date must be in <a href="https://www.iso.org/fr/iso-8601-date-and-time-format.html">ISO 8601</a> format.</td></tr><tr><td><code>invoice.expiresAt</code></td><td>body</td><td><code>string</code></td><td>The date on which the invoice will expires. The date must be in <a href="https://www.iso.org/fr/iso-8601-date-and-time-format.html">ISO 8601</a> format.</td></tr><tr><td><code>paymentFee.amount</code></td><td>body</td><td><code>float</code></td><td>The amount of payment fees<br>applied to the transaction.</td></tr><tr><td><code>paymentFee.currency</code></td><td>body</td><td><code>string</code></td><td>The currency of payment fees<br>applied to the transaction. The<br>currency must be in <a href="https://www.iso.org/fr/iso-4217-currency-codes.html">ISO 4217</a><br>format.</td></tr><tr><td><code>externalTransactionId</code></td><td>body</td><td><code>string</code></td><td>The transaction external identifier provide by payment processor.</td></tr><tr><td><code>result</code></td><td>body</td><td><code>object</code></td><td>The transaction's result.</td></tr><tr><td><code>result.origin</code></td><td>body</td><td><code>object</code></td><td>The transaction's result originator.</td></tr><tr><td><code>result.status</code></td><td>body</td><td><code>enum</code></td><td><p>The transaction's result status. The avalaible values are: <code>COMPLETED</code>,  <code>NEEDS_MERCHANT_VALIDATION</code>, <code>CANCELED</code>,  <code>REFUSED</code> , <code>FAILED</code>  </p><p> and <code>REVERSED</code> .</p></td></tr><tr><td><code>result.statusReason</code></td><td>body</td><td><code>string</code></td><td>The transaction's result status<br>reason.</td></tr><tr><td><code>Authorization</code></td><td>header</td><td><code>string</code></td><td>The request is secured by the<br>HTTP Signature Authentication<br>protocol.</td></tr><tr><td><code>Content-Type</code></td><td>header</td><td><code>string</code></td><td>Set the MIME type for the request.</td></tr></tbody></table>

### Exemple de requête avec authentification par mot de passe

<pre class="language-json"><code class="lang-json">curl -X POST -i 'callbackUrl' \
-H 'Host: acme.org' \
-H 'Content-Type: application/json' \
-H 'Date: Thu, 01 Dec 2022 19:08:22 +0000' \
-H 'Digest: SHA-
256=NjQzMWNjYWMwNjdkYTA5ZWFiZTJiZDMyMDU3NmQxOWEyM2RmNTYyMzMyMDcyOTliMTJmMzAx
YjY1ZDZkOTYzMg==' \
-H 'Signature: keyId="fbab3ccc-719e-11ed-93ad-02420a0003c1",algorithm="hmac-
sha256",headers="(request-target) content-type date
digest",signature="fiFBCK8NWWhvk6fJul8ezzpVXSh9q30VRO8qn3XGxTQ="' \
-H 'Authorization: Signature keyId="2bc56634-673c-11ed-acf4-
0242ac13000e",algorithm="hmac-sha256",headers="(request-target) content-type
date digest",signature="fiFBCK8NWWhvk6fJul8ezzpVXSh9q30VRO8qn3XGxTQ="' \
-d '{
    "id": "63a368858622d5ded108e4b3",
    "payment": {
        "id": "63a368858622d5ded108e4b2",
        "type": "full",
        "application": {
            "id": "b3695b9c-816b-11ed-8083-32706358435f",
            "name": "banking"
        },
        "invoice": {
            "id": "1",
            "customerId": "1",
            "totalAmount": {
                "amount": 1000,
                "currency": "XOF"
            },
            "issuedAt": "2022-12-21T20:11:49+00:00"
        },
        "extras": [],
        "totalAmountAlreadyPaid": {
            "amount": 1000,
            "currency": "XOF"
        }
    },
    "invoice": {
        "id": "1",
        "customerId": "1",
        "totalAmount": {
            "amount": 1000,
            "currency": "XOF"
        },
        "issuedAt": "2022-12-21T20:11:49+00:00"
    },
    "paymentFee": {
        "amount": 0,
        "currency": "XOF"
    },
    "id": "63a368858622d5ded108e4b3",
<strong>    "result": {
</strong>        "origin": "processor",
        "status": "COMPLETED"
    }
}'
</code></pre>

### Comment valider une demande de notification de paiement ?

La demande de notification de paiement instantanée (IPN) est sécurisée par l'authentification par signature HTTP.

Vous trouverez ci-dessous un exemple de code PHP permettant de traiter les demandes de notification de paiement :

```json
// Fetch application secret configuration parameters.
$applicationSecret = 'app!secret';
$body = json_decode(file_get_contents('php://input'), true);
$transactionId = $body['id'];
$transactionStatus = $body['result']['status'];
$invoiceId = $body['invoice']['id'];
$invoiceTotalAmount = $body['invoice']['totalAmount']['amount'];
$paymentFee = $body['paymentFee']['amount'];
/**
* Validate callback authenticity.
*/
$components = [];
$headers = array_change_key_case(getallheaders(), \CASE_LOWER);
foreach (explode(',', $headers['signature'] ?? '') as $value) {
    if (!$component = explode('=', $value, 2)) {
        continue;
    }
    $components[$component[0]] = trim($component[1], '"');
}
if (array_diff(['keyId', 'algorithm', 'headers', 'signature'],
array_keys($components))) {
    die('Payment failed');
}
if ('hmac-sha256' !== $components['algorithm']) {
    die('Payment failed');
}
$signature = [];
foreach (explode(' ', strtolower($components['headers'])) as $header) {
    $signature[] = sprintf('%s: %s', $header, '(request-target)' !== $header
? $headers[$header] : sprintf('%s %s',
strtolower($_SERVER['REQUEST_METHOD']), $_SERVER['REQUEST_URI']));
}
if (false === hash_equals(base64_encode(hash_hmac('sha256',
implode(\PHP_EOL, $signature), applicationSecret, true)),
$components['signature'])) {
    die('Payment failed');
}
/**
* Validate transaction status.
*/
if ('COMPLETED' !== transactionStatus) {
die('Payment failed');
}
// Busines Logic here
// ...
```

### Statut de la transaction

La valeur et la description du statut de la transaction

<table><thead><tr><th width="249">Value</th><th>Reason</th></tr></thead><tbody><tr><td><code>PENDING</code> </td><td>We’re reviewing the transaction. We’ll send your payment to the recipient after your payment source has been verified.</td></tr><tr><td><code>PROCESSING</code> </td><td>We’re processing your payment and the transaction should be<br>completed shortly.</td></tr><tr><td><code>CANCELED</code> </td><td>You canceled your payment, and the money was credited back to your account.</td></tr><tr><td><code>COMPLETED</code> </td><td>The transaction was successful and the money is in the recipient’s account.</td></tr><tr><td><code>REFUSED</code> </td><td>The recipient didn’t receive your payment. If you still want to make your payment, we recommend that you try again.</td></tr><tr><td><code>FAILED</code> </td><td>Your payment didn’t go through. We recommend that you try your payment again.</td></tr><tr><td><code>RESERVED</code> </td><td>Either you canceled the transaction or we did.</td></tr><tr><td><code>NEEDS_MERCHANT_VALIDATION</code> </td><td>Either you awaiting merchant validation.</td></tr></tbody></table>
