> For the complete documentation index, see [llms.txt](https://gitbook.umiverse.io/sdk/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook.umiverse.io/sdk/umiverse-sdk-doc/game-recharge/handle-recharge-completion.md).

# Handle Recharge Completion

**Overview**

Once a user completes the payment on the UMIVERSE platform, the platform will send a notification to the merchant’s configured callback URL. The game can use this notification to process the recharge result.

<figure><img src="/files/Tgl4ITaNsFJh2p3zFHb2" alt=""><figcaption></figcaption></figure>

**Callback Notification Format**

The UMIVERSE platform sends the following information to the merchant’s callback URL:

```javascript
const params = {
    tradeState: "SUCCESS",           // String: Transaction status ("SUCCESS" or "FAIL")
    platformOrderId: "PLATFORM123",  // String: UMIVERSE platform transaction ID
    merchantId: "MERCHANT01",        // String: Merchant ID to prevent tampering
    orderId: "ORDER12345",           // String: Order ID to uniquely identify the transaction
    amount: 50,                      // Number: Recharge amount in USD
    description: "Game coins",       // String: Description of the order
    extraParams: "game-specific-data", // String: Additional data from the original request
    ts: Math.floor(Date.now() / 1000), // Number: Current timestamp
    sign: "callback_signature",      // String: Signature for verification
};
```

**Signature Verification**

To verify the authenticity of the notification:

1\. Concatenate the values in the params object into a string (excluding sign).

2\. Append the current timestamp (ts) and the secret key (**UMI-API-SECRET**) to the string.

3\. Generate the MD5 hash and compare it to the sign value in the notification.

```javascript
function verifySign(ts, params, key = "UMI-API-SECRET") {
    let str = "";
    for (const key in params) {
        if (key !== "sign" && params.hasOwnProperty(key)) {
            str += `${params[key]}`;
        }
    }
    str += `${ts}${key}`;
    const generatedSign = MD5(str).toString();
    return generatedSign === params.sign;
}
```

**Example Notification Handler:**

```javascript
app.post("/recharge/callback", (req, res) => {
    const params = req.body;

    // Verify the signature
    const isValid = verifySign(params.ts, params, "UMI-API-SECRET");
    if (isValid && params.tradeState === "SUCCESS") {
        // Process the successful recharge
        console.log("Recharge successful:", params);
        res.status(200).send("Recharge processed successfully");
    } else {
        // Handle failure or invalid signature
        console.error("Invalid recharge notification or failure:", params);
        res.status(400).send("Invalid recharge notification");
    }
});
```

**Recharge Workflow Summary**

**1. Initiate Recharge Request:**

• The game iframe sends a postMessage with recharge details to the UMIVERSE platform.

**2. User Completes Payment:**

• The UMIVERSE platform presents the payment interface to the user.

**3. Process Recharge Notification:**

• The UMIVERSE platform sends a callback to the configured URL upon payment completion.

• The game server verifies the notification and updates the user’s account accordingly.
