Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions payments/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,14 @@
# ---------------
# Hook on document methods and events

# doc_events = {
# "*": {
# "on_update": "method",
# "on_cancel": "method",
# "on_trash": "method"
# }
# }
doc_events = {
"Subscription Plan": {
# on_update (post-save), not validate: the Stripe sync makes live API calls,
# which must never run inside the save transaction where a Stripe outage
# would block/roll back the user's save.
"on_update": "payments.payment_gateways.stripe_subscription_sync.sync_stripe_price",
},
}

# Scheduled Tasks
# ---------------
Expand Down
4 changes: 4 additions & 0 deletions payments/patches.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pre_model_sync]

[post_model_sync]
payments.patches.add_stripe_custom_fields
Empty file added payments/patches/__init__.py
Empty file.
13 changes: 13 additions & 0 deletions payments/patches/add_stripe_custom_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (c) Frappe Technologies Pvt. Ltd. and contributors
# License: MIT. See LICENSE
#
# Installs the Stripe integration custom fields (Customer.stripe_customer_id,
# Subscription.stripe_subscription_id / stripe_customer_id,
# Payment Entry.stripe_payment_intent) on existing sites. make_custom_fields()
# is idempotent, so re-running is safe.

from payments.utils import make_custom_fields


def execute():
make_custom_fields()
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,56 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"fieldname": "configuration_section",
"fieldtype": "Section Break",
"label": "Configuration"
},
{
"default": "Hosted Checkout",
"description": "Hosted Checkout redirects to a Stripe-hosted page (recommended, SCA/3DS ready). Embedded Elements renders the card form on this site.",
"fieldname": "checkout_mode",
"fieldtype": "Select",
"label": "Checkout Mode",
"options": "Hosted Checkout\nEmbedded Elements"
},
{
"default": "0",
"description": "If enabled, a Subscription Plan's Stripe price is auto-synced from its ERPNext cost on save.",
"fieldname": "sync_subscription_price",
"fieldtype": "Check",
"label": "Sync Subscription Plan Price to Stripe"
},
{
"fieldname": "configuration_cb",
"fieldtype": "Column Break"
},
{
"default": "Bill From Cycle One",
"description": "Bill From Cycle One: Stripe bills price×quantity immediately as the first invoice. Charge Now + Defer First Cycle: charge the Payment Request grand total now and defer the subscription's first billing to the next cycle.",
"fieldname": "subscription_billing_model",
"fieldtype": "Select",
"label": "Subscription Billing Model",
"options": "Bill From Cycle One\nCharge Now + Defer First Cycle"
},
{
"fieldname": "webhooks_section",
"fieldtype": "Section Break",
"label": "Webhooks"
},
{
"description": "Stripe webhook signing secret (whsec_...). Required for the webhook endpoint to verify and process events.",
"fieldname": "webhook_secret",
"fieldtype": "Password",
"label": "Webhook Signing Secret"
},
{
"description": "Point a Stripe webhook endpoint at this URL (copy into the Stripe dashboard).",
"fieldname": "webhook_endpoint",
"fieldtype": "Data",
"label": "Webhook URL",
"read_only": 1
}
],
"has_web_view": 0,
Expand All @@ -277,7 +327,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2022-07-24 13:32:14.429916",
"modified": "2026-06-26 00:00:00.000000",
"modified_by": "Administrator",
"module": "Payment Gateways",
"name": "Stripe Settings",
Expand Down
Loading