feat: add PaymentController v2 architecture#192
Conversation
|
Seems to be nice work, better than me, tests etc. will test it on next update |
|
Using Stripe with PaymentController (before ERPNext integration) The ERPNext Payment Request doctype doesn't yet support the new PaymentController architecture. A small PR (~50 lines) is needed there to detect v2 gateways and call PaymentController.initiate(). Until then, you can still use and test this implementation by linking directly to the checkout page. Direct Usage Generate payment URLs in this format: Or programmatically: from frappe.utils import get_url params = { Security Note The URL parameters are validated server-side against the reference document. If a reference_doctype and reference_docname are provided, the amount and currency are fetched from that document directly, preventing URL tampering. Webhooks Configure your Stripe webhook to point to: Events: payment_intent.succeeded, payment_intent.payment_failed, payment_intent.canceled |
Add support for the new PaymentController architecture from frappe/payments. When a payment gateway implements PaymentController (v2), Payment Request uses the standardized flow. Existing v1 gateways continue working unchanged. Changes: - Add _is_v2_gateway() to detect PaymentController-based gateways - Add _process_v2_gateway() for v2 payment flow - Add get_tx_data() for standardized transaction data - Branch between v1/v2 flows in before_submit() The v2 flow uses PaymentController.initiate() to create a Payment Session Log and generates a standard payment URL (/pay?s=<psl_name>) that works with the payments app's unified checkout experience. Tested with Stripe gateway - Payment Request submission creates correct Payment Session Log and payment page loads successfully. Related: frappe/payments#192
|
https://github.com/0spinboson/erpnext/tree/feat/payment-controller-v2-support < here's a companion patch to test the new gateway approach blaggacao came up with for erpnext |
@0spinboson will you submit this PR to erpnext |
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
|
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Changes: - Add _is_v2_gateway() helper to detect PaymentController-based gateways - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data Related: frappe/payments#192
e8e80ae to
9453739
Compare
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Core changes: - Add _is_v2_gateway() helper delegating to payments.utils.is_v2_gateway() - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data - Store PSL reference for debugging and reconciliation Performance optimization: - Consolidate existence check with document fetch (single DB call) Security & privacy hardening: - Whitelist only payment-relevant contact fields (first_name, last_name, email_id, email, phone) instead of exposing full Contact.as_dict() - Whitelist only payment-relevant address fields (address_line1/2, city, state, pincode, country) instead of full Address.as_dict() - Add catch-all exception handler to prevent submission failures - Log full exception server-side, show generic message to users Compatibility: - Add 'email' key alongside 'email_id' for gateway compatibility - Normalize first_name to prevent None in tx_data - Use get_request_amount() for partial payment support Test coverage: - v2 gateway detection (None, empty string, nonexistent, v1, v2) - Flow selection (v2 vs v1 mutual exclusion) - tx_data structure validation - Partial payment amount handling - PII minimization (whitelisted fields only) - Exception handling Related: frappe/payments#192
|
okay, should be done now. Reorganized code changes logically into commits. Apologies for not doing this in my own fork first. |
fc7471c to
9947cc7
Compare
Adds documentation for the new PaymentController v2 architecture in the payments app, covering: - Architecture overview and components - Integration with ERPNext Payment Request - Implementing v2 payment gateways - Stripe v2 configuration guide - API reference - Troubleshooting guide Related: frappe/erpnext#51723, frappe/payments#192
Adds support for the new PaymentController interface from frappe/payments. This enables Payment Request to work with v2 payment gateways (like the refactored Stripe integration) while maintaining full backward compatibility with existing v1 gateways. Core changes: - Add _is_v2_gateway() helper delegating to payments.utils.is_v2_gateway() - Branch before_submit to use appropriate flow (v2 vs v1) - Add _process_v2_gateway() method using PaymentController.initiate() - Add get_tx_data() to prepare standardized transaction data - Store PSL reference for debugging and reconciliation Performance optimization: - Consolidate existence check with document fetch (single DB call) Security & privacy hardening: - Whitelist only payment-relevant contact fields (first_name, last_name, email_id, email, phone) instead of exposing full Contact.as_dict() - Whitelist only payment-relevant address fields (address_line1/2, city, state, pincode, country) instead of full Address.as_dict() - Add catch-all exception handler to prevent submission failures - Log full exception server-side, show generic message to users Compatibility: - Add 'email' key alongside 'email_id' for gateway compatibility - Normalize first_name to prevent None in tx_data - Use get_request_amount() for partial payment support Test coverage: - v2 gateway detection (None, empty string, nonexistent, v1, v2) - Flow selection (v2 vs v1 mutual exclusion) - tx_data structure validation - Partial payment amount handling - PII minimization (whitelisted fields only) - Exception handling Related: frappe/payments#192
f8927b6 to
f82df10
Compare
f82df10 to
6263703
Compare
Add support for the new PaymentController interface from frappe/payments, enabling Payment Request to work with v2 gateways while maintaining backward compatibility with v1. Related: frappe/payments#192
Add support for the new PaymentController interface from frappe/payments, enabling Payment Request to work with v2 gateways while maintaining backward compatibility with v1. Related: frappe/payments#192
|
(I will update this PR tonight or tomorrow as I found a few more issues to address and code to refactor. just fyi.) |
9d33c09 to
15a8dfc
Compare
Add a template-method based PaymentController that orchestrates the full payment lifecycle: initiate -> proceed -> process_response. - PaymentController base class with abstract gateway contracts - Payment Session Log DocType for tracking payment state - Payment Button DocType for gateway selection UI - /pay universal payment endpoint with multi-gateway support - Type system (TxData, Proceeded, Processed, SessionStates) - Custom exception hierarchy for structured error handling - TX data filtering whitelist to prevent parameter tampering - Concurrency guards with document locking and terminal state checks - is_v2_gateway() utility for detecting v2-compatible gateways - Fix delete_custom_fields to use composite key lookup - Fix get_checkout_url to route through get_payment_gateway_controller - Add Payment Session Log link field on Payment Request - Integration tests for controller lifecycle
15a8dfc to
cdf1bbc
Compare
Add support for the new PaymentController interface from frappe/payments, enabling Payment Request to work with v2 gateways while maintaining backward compatibility with v1. Related: frappe/payments#192
Add support for the new PaymentController interface from frappe/payments, enabling Payment Request to work with v2 gateways while maintaining backward compatibility with v1. Related: frappe/payments#192
Summary
Adds a
PaymentControllerbase class that standardizes payment gateway integrations using the template method pattern. Based on the architecture from PR #53 by @blaggacao.The first gateway implementation (Stripe PaymentIntent) is on the
feat/stripe-payment-intentbranch, stacked on this one.What's included
PaymentController— abstract base class orchestratinginitiate → proceed → process_responsePayment Session Log— DocType for tracking payment state with document locking and terminal state checksPayment Button— DocType for gateway selection UI/pay— gateway-agnostic payment endpointpayments/types.py— data contracts:TxData,Initiated,Proceeded,Processed,SessionStatespayments/exceptions.py— structured error hierarchyis_v2_gateway()— utility for consumers to detect v2-compatible gatewaysdelete_custom_fieldsto use composite key lookupget_checkout_urlto route throughget_payment_gateway_controllerPayment Session Loglink field on Payment RequestThe interface currently supports the
chargeflow. Subscription, pre-authorization, and mandate flows are planned.Tests
28 Python tests covering controller lifecycle, PSL state management, PaymentButton properties, and legacy compatibility.
Breaking changes
None. Existing gateway integrations are unaffected.