Integrations

Integrations

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

Building Custom Gateway

1. Gateway Settings Doctype

Create gateway settings doctype extending standard controller pattern:

class CustomGatewaySettings(Document):
    supported_currencies = ("USD", "EUR", "GBP")

    def on_update(self):
        create_payment_gateway(
            "Custom Gateway",
            settings="Custom Gateway Settings",
            controller=self.name
        )
        call_hook_method("payment_gateway_enabled", gateway="Custom Gateway")

    def validate_transaction_currency(self, currency):
        if currency not in self.supported_currencies:
            frappe.throw(_("Currency {0} not supported").format(currency))

    def get_payment_url(self, **kwargs):
        return f"https://checkout.customgateway.com/pay?{urlencode(kwargs)}"

2. Doctype JSON Configuration

{
  "doctype": "DocType",
  "name": "Custom Gateway Settings",
  "fields": [
    {"fieldname": "api_key", "fieldtype": "Data", "label": "API Key"},
    {"fieldname": "api_secret", "fieldtype": "Password", "label": "API Secret"},
    {"fieldname": "use_sandbox", "fieldtype": "Check", "label": "Use Sandbox"}
  ]
}

3. Checkout Template

Create checkout page template:

{% extends "templates/web.html" %}
{% block page_content %}
<form id="payment-form" action="{{ callback_url }}" method="POST">
    <input type="hidden" name="token" value="{{ token }}">
    <button type="submit">Pay {{ amount }} {{ currency }}</button>
</form>
{% endblock %}

4. Callback Handler

@frappe.whitelist(allow_guest=True)
def handle_callback():
    token = frappe.form_dict.token
    integration_request = frappe.get_doc("Integration Request", token)

    # Verify payment with gateway
    payment_status = verify_payment_with_gateway(token)

    integration_request.update_status(
        data={"transaction_id": payment_status.txn_id},
        status="Completed" if payment_status.success else "Failed"
    )

    # Trigger callback on reference document
    data = json.loads(integration_request.data)
    if data.get("reference_doctype"):
        doc = frappe.get_doc(data["reference_doctype"], data["reference_docname"])
        doc.run_method("on_payment_authorized", "Completed")

5. App Hooks Configuration

# custom_gateway/hooks.py
doctype_js = {
    "Custom Gateway Settings": "custom_gateway/js/settings.js"
}

payment_gateway_controller = {
    "Custom Gateway": "custom_gateway.controllers.get_controller"
}
Last updated 2 months ago
Was this helpful?
Thanks!