Embedded Integration — Python

Build your own checkout in Python — hash, direct sale, 3DS, capture, webhooks.

Embedded Integration lets you collect card data on your website and charge via DigetPay from your Python backend. You build the checkout UI — including Apple Pay if needed (separate guide).

PCI DSS: Embedded Integration requires secure handling of card data (SAQ D or equivalent). Prefer Hosted Checkout unless compliance approves embedded card collection.

Never send card data from browser JavaScript directly to DigetPay. Post card fields to your server first, then your server calls the embedded sale APIs.

Prerequisites: Embedded Integration Overview, Sandbox Setup, Python 3.10+ with requests.


Architecture

sequenceDiagram
  participant Browser as Customer Browser
  participant Shop as Your Python Server
  participant API as DigetPay API

  Browser->>Shop: POST checkout form (card fields)
  Shop->>Shop: Compute MD5 hash
  Shop->>API: POST /payment/s2s/sale
  API-->>Shop: status + html (3DS if needed)
  Shop->>Browser: Render 3DS or success page
  API->>Shop: Webhook notification

Step 1 — Configuration

# config/digetpay.py
import os

API_BASES = {
    "staging": "https://fin-api.digetpay.com/v1",
    "production": "https://api.digetpay.com/v1",
}

environment = os.getenv("DIGETPAY_ENV", "staging")
api_key = os.getenv("DIGETPAY_API_KEY", "")
api_base = API_BASES[environment]

if not api_key:
    raise RuntimeError("DIGETPAY_API_KEY is not set")

Step 2 — Hash helper

# digetpay_hash.py
import hashlib
import re

def digetpay_embedded_hash(email: str, card_number: str, api_key: str) -> str:
    card = re.sub(r"\s+", "", card_number)
    reversed_email = email[::-1]
    reversed_card = (card[:6] + card[-4:])[::-1]
    raw = (reversed_email + api_key + reversed_card).upper()
    return hashlib.md5(raw.encode()).hexdigest()

Full explanation: Request Hash (MD5).


Step 3 — Embedded client

# digetpay_embedded_client.py
import requests
from config.digetpay import api_base, api_key
from digetpay_hash import digetpay_embedded_hash

HEADERS = {"Content-Type": "application/json", "x-api-key": api_key}


def _request(method: str, path: str, body: dict | None = None) -> dict:
    resp = requests.request(method, f"{api_base}{path}", headers=HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    return resp.json()


def direct_sale(order: dict, card: dict, customer: dict, success_url: str, failure_url: str) -> dict:
    card_number = card["cardNumber"].replace(" ", "")
    hash_value = digetpay_embedded_hash(customer["email"], card_number, api_key)
    return _request("POST", "/payment/s2s/sale", {
        "orderId": order["orderId"],
        "amount": order["amount"],
        "currency": order.get("currency", "SAR"),
        "paymentMethod": "card",
        "auth": order.get("auth", "N"),
        "card": {
            "cardNumber": card_number,
            "cardExpiryMonth": card["cardExpiryMonth"],
            "cardExpiryYear": card["cardExpiryYear"],
            "cardCvv": card["cardCvv"],
            "cardHolder": card["cardHolder"],
        },
        "customer": customer,
        "successUrl": success_url,
        "failureUrl": failure_url,
        "hash": hash_value,
    })


def capture(transaction_id: str, amount: float) -> dict:
    return _request("POST", "/payment/s2s/capture", {"transactionId": transaction_id, "amount": amount})


def void_transaction(transaction_id: str) -> dict:
    return _request("POST", "/payment/s2s/void", {"transactionId": transaction_id})


def get_status(transaction_id: str) -> dict:
    return _request("POST", f"/payment/s2s/status/{transaction_id}")

Step 4 — Process payment route

Flask example:

# routes/payment.py
from flask import Blueprint, request, redirect, Response
from digetpay_embedded_client import direct_sale

payment_bp = Blueprint("payment", __name__)


@payment_bp.route("/process-payment", methods=["POST"])
def process_payment():
    try:
        result = direct_sale(
            order={"orderId": request.form["order_id"], "amount": float(request.form["amount"]), "auth": "N"},
            card={
                "cardNumber": request.form["card_number"],
                "cardExpiryMonth": request.form["exp_month"],
                "cardExpiryYear": request.form["exp_year"],
                "cardCvv": request.form["cvv"],
                "cardHolder": request.form["card_holder"],
            },
            customer={"name": request.form["card_holder"], "email": request.form["email"], "phone": request.form["phone"]},
            success_url="https://yourstore.com/payment/3ds-return",
            failure_url="https://yourstore.com/payment/failed",
        )
        data = result.get("data") or result
        html = data.get("html") or data.get("htmlContent")
        if html:
            return Response(html, mimetype="text/html")
        if data.get("status") == "APPROVED":
            return redirect("/order/complete")
        return redirect("/payment/failed")
    except Exception as e:
        return "Payment failed", 500

For Apple Pay, use a separate button and server flow — Apple Pay Embedded. See Apple Pay Code (Python).


Step 5 — Capture, void, and webhooks

from digetpay_embedded_client import capture, void_transaction

capture("2232e99b-0257-47d5-bbfd-022c8951767f", 10.0)
void_transaction("2232e99b-0257-47d5-bbfd-022c8951767f")

Webhook handler — see Webhooks Code (Python).


Next steps


Did this page help you?