Charge Webhook
A55 sends a POST to your webhook_url whenever a charge status changes. The webhook payload contains only the essential fields — use the charge UUID to fetch the full details from the API.
Payload fields
| Field | Type | Description |
|---|---|---|
charge_uuid | UUID | Unique charge identifier |
status | string | New charge status (see table below) |
transaction_reference | string | ID sent by the client / acquirer transaction reference |
subscription_uuid | UUID or null | Subscription identifier — present only if the charge belongs to a subscription |
payment_link_uuid | UUID or null | Payment link identifier — present only if the charge was created via a payment link |
Payload example
{
"charge_uuid": "fe5e2c1e-b3fb-4cc4-bb28-004da37d5804",
"status": "confirmed",
"transaction_reference": "txn-abc-123",
"subscription_uuid": null,
"payment_link_uuid": null
}
All possible statuses
| Status | Description |
|---|---|
confirmed | Transaction approved |
pending | Awaiting 3DS challenge |
issued | Charge created, awaiting processing (e.g. Apple Pay SDK) |
canceled | Canceled after issuance or 3DS challenge not completed |
paid | Charge settled |
error | Transaction failed or declined |
refunded | Refund completed |
refund_error | Error during refund |
chargeback_refunded | Chargeback refunded |
chargeback_requested | Chargeback requested |
chargeback_reversed | Chargeback reversed |
pre_chargeback_resolution | Pre-chargeback resolution in progress |
Fetching full charge details
The webhook payload is intentionally minimal. After receiving it, call the API with your Bearer token to get the complete charge object:
curl https://api.a55.tech/api/v1/bank/wallet/charge/{charge_uuid}/ \
-H "Authorization: Bearer $ACCESS_TOKEN"
The response is the full charge object with all fields including local_currency, currency, installments, action_url, applepay_payload, and more.
Webhook is the trigger, API is the source of truth
Use the webhook to know when something changed, then call GET /api/v1/bank/wallet/charge/{uuid}/ to get full details. Never rely solely on the redirect URL — it can be spoofed.
Handler examples
- Python (Flask)
- JavaScript (Express)
from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
processed = set()
ACCESS_TOKEN = "your_bearer_token"
@app.route("/webhook", methods=["POST"])
def charge_webhook():
data = request.get_json()
charge_uuid = data.get("charge_uuid")
status = data.get("status")
# Deduplicate
if charge_uuid in processed:
return jsonify(status="duplicate"), 200
processed.add(charge_uuid)
# Fetch full charge details from the API
charge = requests.get(
f"https://api.a55.tech/api/v1/bank/wallet/charge/{charge_uuid}/",
headers={"Authorization": f"Bearer {ACCESS_TOKEN}"},
).json()
# Route by status
if status == "confirmed":
fulfill_order(charge)
elif status == "error":
notify_customer(charge)
elif status == "refunded":
credit_customer(charge)
elif status in ("chargeback_requested", "chargeback_refunded"):
flag_for_review(charge)
return jsonify(status="accepted"), 200
const express = require("express");
const fetch = require("node-fetch");
const app = express();
app.use(express.json());
const processed = new Set();
const ACCESS_TOKEN = "your_bearer_token";
app.post("/webhook", async (req, res) => {
const { charge_uuid, status } = req.body;
// Respond immediately
res.sendStatus(200);
// Deduplicate
if (processed.has(charge_uuid)) return;
processed.add(charge_uuid);
// Fetch full charge details from the API
const response = await fetch(
`https://api.a55.tech/api/v1/bank/wallet/charge/${charge_uuid}/`,
{ headers: { Authorization: `Bearer ${ACCESS_TOKEN}` } }
);
const charge = await response.json();
// Route by status
const actions = {
confirmed: fulfillOrder,
error: notifyCustomer,
refunded: creditCustomer,
chargeback_requested: flagForReview,
chargeback_refunded: flagForReview,
};
if (actions[status]) actions[status](charge);
});
Best practices
| Practice | Why |
|---|---|
Return 200 immediately | Avoids timeouts and duplicate deliveries |
| Process in background | Keeps response time under 30 s |
Deduplicate by charge_uuid | Handles retried webhooks safely |
| Fetch full details via API | Webhook payload is minimal by design |
| Log raw payloads | Enables debugging without re-delivery |