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", 500For 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
Updated about 1 month ago
