Callbacks#

Platega authenticates a callback by echoing your own X-MerchantId and X-Secret headers back at you; there is no signature over the body. The comparison is done with hmac.compare_digest(), so a wrong secret cannot be recovered by timing the response.

Verification of incoming callbacks.

Platega authenticates a callback by echoing the merchant’s own credentials back in the X-MerchantId and X-Secret headers; there is no signature over the body. Verification is therefore a comparison of two secrets, which is only safe done in constant time.

aioplatega.callback.verify_callback(headers, body, *, merchant_id, secret, model=<class 'aioplatega.types.callback_payload.CallbackPayload'>)[source]#

Authenticate a callback and parse its body.

Framework-agnostic: pass whatever mapping of headers and raw body your web framework exposes.

Parameters:
  • headers (Mapping[str, str]) – Request headers. Looked up case-insensitively.

  • secret (str) – The API secret to compare the X-Secret header against.

  • merchant_id (str) – The merchant id to compare X-MerchantId against.

  • body (str | bytes) – Raw request body, decoded as UTF-8 if given as bytes.

  • model (type[Any]) – Model to parse the body into. Pass SubscriptionChargeCallback or SubscriptionStatusCallback for the subscription callbacks, whose fields are PascalCase.

Return type:

Any

Returns:

The parsed callback body, an instance of model.

Raises:

PlategaValidationError – If the credentials do not match, or the body is empty, malformed, or missing required fields. Never reveals which of the two credentials was wrong.

Example

@app.route("/callback", methods=["POST"])
def callback():
    try:
        payload = client.verify_callback(request.headers, request.get_data())
    except PlategaValidationError:
        return "", 401
    if payload.status == PaymentStatus.CONFIRMED:
        mark_paid(payload.payload)
    return "", 200