Skip to content

Commit

Permalink
# This is a combination of 12 commits.
Browse files Browse the repository at this point in the history
# This is the 1st commit message:

[FIX] Fixed recurring payments

# This is the commit message #2:

[FIX] Resolved all suggestion

# This is the commit message #3:

[ADD] Add precommit rules

# This is the commit message #4:

[ADD] Add stripe library

# This is the commit message #5:

[ADD] Add stripe library

# This is the commit message #6:

[FIX] Fixed precommit error

# This is the commit message #7:

[FIX] Fixed precommit error

# This is the commit message #8:

[FIX] Fixed precommit flake error

# This is the commit message #9:

[FIX] Fixed translation error in account_move.py and spaces inside summary

# This is the commit message #10:

[FIX] Fixed translation error in account_move.py and spaces inside summary

# This is the commit message #11:

[FIX] Fixed payment transaction and design modular

# This is the commit message #12:

[FIX] Fixed test implementation
  • Loading branch information
mjavint committed Jan 21, 2025
1 parent 5329d7c commit 0b8a36e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 68 deletions.
66 changes: 30 additions & 36 deletions recurring_payment_stripe/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def action_register_payment(self):
payment on subscriptions.
"""
for invoice in self:
res = super(AccountMove, self).action_register_payment()
# Find the subscription associated with the invoice, if it exists
subscription = invoice.subscription_id

Expand All @@ -42,42 +43,43 @@ def action_register_payment(self):
)

# Handling the result of the PaymentIntent
if payment_intent["status"] != "succeeded":
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 - {payment_intent['id']}",
}
payment = Payment.create(payment_vals)
payment.action_post()
invoice.payment_state = "paid"
elif payment_intent["status"] == "requires_action":
raise UserError(
_("Payment failed with status: %s")
% payment_intent["status"]
_("Payment requires additional authentication (3D Secure).")
)
else:
raise UserError(
f"Stripe payment error: {payment_intent['status']}"
)

# 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 - {payment_intent['id']}",
}
payment = Payment.create(payment_vals)
payment.action_post()
invoice.payment_state = "paid"

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

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

def _create_token(self, subscription):
provider = subscription.provider_id
# Search for an existing payment token for the given provider and
# partner
# Search for an existing payment token for the given provider and partner
token = self.env["payment.token"].search(
[
("provider_id", "=", provider.id),
Expand Down Expand Up @@ -110,20 +112,13 @@ def _create_token(self, subscription):
# Retrieve the default payment method for the customer,
# or create one if it doesn't exist
new_token.stripe_payment_method = (
stripe.PaymentMethod.list(
customer=customer.id,
type="card",
limit=1,
)
stripe.PaymentMethod.list(customer=customer.id, type="card", limit=1)
.data[0]
.id
if stripe.PaymentMethod.list(
customer=customer.id, type="card", limit=1
).data
else stripe.Customer.create_source(
customer.id,
source="tok_visa",
).id
else stripe.Customer.create_source(customer.id, source="tok_visa").id
)

# Assign the new token to the variable
Expand All @@ -143,7 +138,6 @@ def cron_process_due_invoices(self):
if subscription and subscription.charge_automatically:
try:
# Register the payment
invoice.action_post()
invoice.action_register_payment()
except Exception as e:
_logger.error(f"Error Processing Due Invoices: {str(e)}")
56 changes: 24 additions & 32 deletions recurring_payment_stripe/tests/test_payment_stripe_recurring.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ def setUpClass(cls):
"invoice_line_ids": [
(
0,
None,
0,
{
"product_id": cls.product_2.id,
"quantity": 3,
"price_unit": 750,
"name": "Test Product",
"quantity": 1,
"price_unit": 100.0,
},
),
)
],
"subscription_id": cls.sub8.id,
}
Expand Down Expand Up @@ -146,41 +146,33 @@ def create_sub(cls, vals):
return rec

def test_action_register_payment(self):
self.assertTrue(
self.invoice.state == "draft",
f"Invoice {self.invoice.id} should be in draft state",
)

self.invoice.cron_process_due_invoices()
token = self.invoice._create_token(subscription=self.sub8)
self.assertTrue(token, "Payment token was not created")

self.assertTrue(
self.invoice.state == "posted",
f"Invoice {self.invoice.id} should be posted",
)
self.assertTrue(
self.invoice.payment_state == "paid",
f"Invoice {self.invoice.id} should be paid",
method_line = self.env["account.payment.method.line"].search(
[("name", "=", self.provider.name)], limit=1
)
self.assertTrue(method_line, "Payment method line was not found")
method = method_line.payment_method_id
self.assertTrue(method, "Payment method was not found")

def test_stripe_payment_intent(self):
stripe.api_key = self.provider.stripe_secret_key
provider = self.sub8.provider_id
stripe.api_key = provider.stripe_secret_key
token = self.invoice._create_token(self.sub8)

# Check if the PaymentIntent was created
payment_intent = stripe.PaymentIntent.create(
# Stripe uses cents
amount=int(self.invoice.amount_total * 100),
currency=self.invoice.currency_id.name.lower(),
customer=token.provider_ref,
payment_method=token.stripe_payment_method,
automatic_payment_methods={"enabled": True},
# For automatic payments without user intervention
off_session=True,
# Confirm the PaymentIntent immediately
confirm=True,
metadata={"odoo_invoice_id": str(self.invoice.id)},
metadata={"odoo_invoice_id": str(self.invoice.name)},
)
self.assertEqual(
payment_intent["status"],
"succeeded",
"PaymentIntent was not successful",
)
self.invoice.action_register_payment()
self.assertTrue(
self.invoice.payment_state == "paid",
"Invoice was not paid",
)

# Check if the payment was successful
self.assertEqual(payment_intent.status, "succeeded")

0 comments on commit 0b8a36e

Please sign in to comment.