Skip to content

Commit

Permalink
Merge pull request #2 from BinhexTeam/16.0-dev
Browse files Browse the repository at this point in the history
[16.0][ADD] recurring_payments_stripe: Add recurring payments with stripe
  • Loading branch information
mjavint authored Nov 28, 2024
2 parents 4aff2af + ea7a9b2 commit fa09388
Show file tree
Hide file tree
Showing 28 changed files with 684 additions and 6 deletions.
2 changes: 1 addition & 1 deletion contract_sale/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Contract from Sale
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:00fb3cdc565442ffcd3351e97d0516ce6f4ceb55402981b183f7e717a1e23173
!! source digest: sha256:c2e49dd78cebc553bbe7e5bfa2c8658e29e120878e688512e9599b43144815dd
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
13 changes: 8 additions & 5 deletions contract_sale/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

/*
:Author: David Goodger ([email protected])
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -274,7 +275,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
Expand All @@ -300,7 +301,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -366,7 +367,7 @@ <h1 class="title">Contract from Sale</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:00fb3cdc565442ffcd3351e97d0516ce6f4ceb55402981b183f7e717a1e23173
!! source digest: sha256:c2e49dd78cebc553bbe7e5bfa2c8658e29e120878e688512e9599b43144815dd
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/contract/tree/16.0/contract_sale"><img alt="OCA/contract" src="https://img.shields.io/badge/github-OCA%2Fcontract-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/contract-16-0/contract-16-0-contract_sale"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/contract&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module allows access to contracts for sale employees without account
Expand Down Expand Up @@ -428,7 +429,9 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.</p>
Expand Down
70 changes: 70 additions & 0 deletions recurring_payments_stripe/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
==============================
Recurring Payments with Stripe
==============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:7aacc5b46917b14e43404143f0ccd1519d1411d580330b8eb8a8ef608fe3a5a1
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fcontract-lightgray.png?logo=github
:target: https://github.com/OCA/contract/tree/16.0/recurring_payments_stripe
:alt: OCA/contract
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/contract-16-0/contract-16-0-recurring_payments_stripe
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/contract&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|


**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/contract/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/contract/issues/new?body=module:%20recurring_payments_stripe%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* Binhex

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/contract <https://github.com/OCA/contract/tree/16.0/recurring_payments_stripe>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions recurring_payments_stripe/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
16 changes: 16 additions & 0 deletions recurring_payments_stripe/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "Recurring Payments with Stripe",
"version": "16.0.1.0.0",
"summary": """ Recurring Payments with Stripe """,
"author": "Binhex, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/contract",
"license": "AGPL-3",
"category": "Subscription Management",
"depends": ["subscription_oca", "payment_stripe", "payment"],
"data": [
"views/sale_subscription_views.xml",
"data/ir_cron.xml",
],
"installable": True,
"auto_install": False,
}
13 changes: 13 additions & 0 deletions recurring_payments_stripe/data/ir_cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<odoo noupdate="1">
<!-- Cron Job para Procesar Facturas Vencidas Diariamente -->
<record id="ir_cron_process_due_invoices" model="ir.cron">
<field name="name">Process Overdue Invoices for Subscriptions</field>
<field name="model_id" ref="recurring_payments_stripe.model_account_move" />
<field name="state">code</field>
<field name="code">model.cron_process_due_invoices()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="active">True</field>
</record>
</odoo>
2 changes: 2 additions & 0 deletions recurring_payments_stripe/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import sale_subscription
from . import account_move
94 changes: 94 additions & 0 deletions recurring_payments_stripe/models/account_move.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import logging

import stripe

from odoo import api, models
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)


class AccountMove(models.Model):
_inherit = "account.move"

def action_register_payment(self):
"""
Override `action_register_payment` to automatically process Stripe
payment on subscriptions.
"""
for invoice in self:
# Find the subscription associated with the invoice, if it exists
subscription = invoice.subscription_id

# Check if the subscription is recurring and has a payment method
if subscription and subscription.charge_automatically:
provider = subscription.provider_id
stripe.api_key = provider.stripe_secret_key
token = self.env["payment.token"].search(
[("provider_id", "=", provider.id)]
)
try:
# Create the PaymentIntent and confirm it immediately
payment_intent = stripe.PaymentIntent.create(
# Stripe usa centavos
amount=int(invoice.amount_total * 100),
currency=invoice.currency_id.name.lower(),
customer=token.provider_ref,
payment_method=token.stripe_payment_method,
# Para pagos automáticos sin intervención del usuario
off_session=True,
# Confirmar el PaymentIntent inmediatamente
confirm=True,
metadata={"odoo_invoice_id": str(invoice.id)},
)

# Manejar el resultado del PaymentIntent
if payment_intent["status"] == "succeeded":
# If the payment is successful, record the payment on the invoice
Payment = self.env["account.payment"].sudo()
payment_vals = {
"journal_id": self.env["account.journal"]
.search([("type", "=", "bank")], limit=1)
.id,
"amount": invoice.amount_total,
"payment_type": "inbound",
"partner_type": "customer",
"partner_id": invoice.partner_id.id,
"payment_method_id": self.env.ref(
"account.account_payment_method_manual_in"
).id,
"ref": f"Stripe PaymentIntent {payment_intent['id']}",
}
payment = Payment.create(payment_vals)
payment.action_post()
invoice.payment_state = "paid"
elif payment_intent["status"] == "requires_action":
raise UserError(
"Payment requires additional authentication (3D Secure)."
)
else:
raise UserError(
f"Stripe payment error: {payment_intent['status']}"
)

except stripe.StripeError as e:
raise UserError(f"Stripe error: {e.user_message or str(e)}")

else:
return super(AccountMove, self).action_register_payment()

@api.model
def cron_process_due_invoices(self):
"""Process payment of overdue invoices for recurring subscriptions."""

for invoice in self:
# Find the subscription associated with the invoice
subscription = invoice.subscription_id

# Check if it's a recurring subscription with Stripe
if subscription and subscription.charge_automatically:
try:
# Register the payment
invoice.action_register_payment()
except Exception as e:
_logger.error(f"Error Processing Due Invoices: {str(e)}")
35 changes: 35 additions & 0 deletions recurring_payments_stripe/models/sale_subscription.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import stripe

from odoo import api, fields, models


class SaleSubscription(models.Model):
_inherit = "sale.subscription"

charge_automatically = fields.Boolean(string="Charge Automatically")
stripe_customer = fields.Char(string="Stripe Customer ID")
provider_id = fields.Many2one(
string="Provider_id",
domain=[("code", "=", "stripe")],
comodel_name="payment.provider",
)

def create_stripe_customer(self):
provider = self.provider_id
if provider:
stripe.api_key = provider.stripe_secret_key

if not self.stripe_customer:
customer = stripe.Customer.create(
email=self.env.user.email,
name=self.env.user.name,
metadata={"odoo_subscription": str(self.id)},
)
self.stripe_customer = customer["id"]
return self.stripe_customer

@api.onchange("charge_automatically")
def _onchange_charge_automatically(self):
for record in self:
if record.charge_automatically:
record.create_stripe_customer()
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit fa09388

Please sign in to comment.