overhaul of paypal handler WIP
Some checks failed
Build and deploy the backend to staging / Build and push image (pull_request) Successful in 3m44s
Run linting on the backend code / Build (pull_request) Successful in 23s
Run testing on the backend code / Build (pull_request) Failing after 3m7s
Build and deploy the backend to staging / Deploy to staging (pull_request) Failing after 35s
Some checks failed
Build and deploy the backend to staging / Build and push image (pull_request) Successful in 3m44s
Run linting on the backend code / Build (pull_request) Successful in 23s
Run testing on the backend code / Build (pull_request) Failing after 3m7s
Build and deploy the backend to staging / Deploy to staging (pull_request) Failing after 35s
This commit is contained in:
@@ -13,6 +13,11 @@ load_dotenv(override=True)
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Environment :
|
class Environment :
|
||||||
|
|
||||||
|
# Load supabase secrets
|
||||||
supabase_url = os.environ['SUPABASE_URL']
|
supabase_url = os.environ['SUPABASE_URL']
|
||||||
supabase_admin_key = os.environ['SUPABASE_ADMIN_KEY']
|
supabase_admin_key = os.environ['SUPABASE_ADMIN_KEY']
|
||||||
supabase_test_user_id = os.environ['SUPABASE_TEST_USER_ID']
|
supabase_test_user_id = os.environ['SUPABASE_TEST_USER_ID']
|
||||||
|
|
||||||
|
# Load paypal secrets
|
||||||
|
paypal_id_sandbox = os.environ['PAYPAL_ID_SANDBOX']
|
||||||
|
paypal_key_sandbox = os.environ['PAYPAL_KEY_SANDBOX']
|
||||||
|
@@ -4,6 +4,9 @@ from pydantic import BaseModel
|
|||||||
from fastapi import HTTPException
|
from fastapi import HTTPException
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from ..configuration.environment import Environment
|
||||||
|
|
||||||
|
|
||||||
# Model for payment request body
|
# Model for payment request body
|
||||||
class PaymentRequest(BaseModel):
|
class PaymentRequest(BaseModel):
|
||||||
@@ -14,13 +17,22 @@ class PaymentRequest(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
# Payment handler class for managing PayPal payments
|
# Payment handler class for managing PayPal payments
|
||||||
class PaymentHandler:
|
class PaypalHandler:
|
||||||
|
|
||||||
payment_id: str
|
# PayPal secrets
|
||||||
|
username = Environment.paypal_id_sandbox
|
||||||
|
password = Environment.paypal_key_sandbox
|
||||||
|
|
||||||
def __init__(self, transaction_details: PaymentRequest):
|
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
transaction_details: PaymentRequest,
|
||||||
|
sandbox_mode: bool = False
|
||||||
|
):
|
||||||
self.details = transaction_details
|
self.details = transaction_details
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
|
self.sandbox = sandbox_mode
|
||||||
|
|
||||||
# Only support purchase of credit 'bundles': 10, 50 or 100 credits worth of trip generation
|
# Only support purchase of credit 'bundles': 10, 50 or 100 credits worth of trip generation
|
||||||
def fetch_price(self) -> float:
|
def fetch_price(self) -> float:
|
||||||
@@ -34,37 +46,40 @@ class PaymentHandler:
|
|||||||
self.logger.error(f"Unsupported currency: {self.details.currency}")
|
self.logger.error(f"Unsupported currency: {self.details.currency}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def create_paypal_payment(self) -> str:
|
|
||||||
"""
|
|
||||||
Creates a PayPal payment and returns the approval URL.
|
|
||||||
"""
|
|
||||||
price = self.fetch_price()
|
|
||||||
payment = paypalrestsdk.Payment({
|
|
||||||
"intent": "sale",
|
|
||||||
"payer": {
|
|
||||||
"payment_method": "paypal"
|
|
||||||
},
|
|
||||||
"transactions": [{
|
|
||||||
"amount": {
|
|
||||||
"total": f"{price:.2f}",
|
|
||||||
"currency": self.details.currency
|
|
||||||
},
|
|
||||||
"description": self.details.description
|
|
||||||
}],
|
|
||||||
"redirect_urls": {
|
|
||||||
"return_url": "http://localhost:8000/payment/success",
|
|
||||||
"cancel_url": "http://localhost:8000/payment/cancel"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if payment.create():
|
def validate(self):
|
||||||
self.logger.info("Payment created successfully")
|
|
||||||
self.payment_id = payment.id
|
|
||||||
|
|
||||||
# Get the approval URL and return it for the user to approve
|
if self.sandbox :
|
||||||
for link in payment.links:
|
validation_url = "https://api-m.sandbox.paypal.com/v1/oauth2/token"
|
||||||
if link.rel == "approval_url":
|
else :
|
||||||
return link.href
|
validation_url = "https://api-m.paypal.com/v1/oauth2/token"
|
||||||
else:
|
|
||||||
self.logger.error(f"Failed to create payment: {payment.error}")
|
# payload for the validation request
|
||||||
raise HTTPException(status_code=500, detail="Payment creation failed")
|
validation_data = {'grant_type': 'client_credentials'}
|
||||||
|
|
||||||
|
# pass the request
|
||||||
|
validation_response = requests.post(
|
||||||
|
url=validation_url,
|
||||||
|
data=validation_data,
|
||||||
|
auth=(self.username, self.password)
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: continue here
|
||||||
|
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def order(self):
|
||||||
|
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
def capture(self):
|
||||||
|
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def cancel(self):
|
||||||
|
|
||||||
|
pass
|
||||||
|
100
backend/src/payments/test.py
Normal file
100
backend/src/payments/test.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
from ..configuration.environment import Environment
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# DOCUMENTATION AT : https://developer.paypal.com/api/rest/requests/
|
||||||
|
|
||||||
|
# username and password
|
||||||
|
username = Environment.paypal_id_sandbox
|
||||||
|
password = Environment.paypal_key_sandbox
|
||||||
|
|
||||||
|
|
||||||
|
######## STEP 1: Validation ########
|
||||||
|
# url for validation post request
|
||||||
|
validation_url = "https://api-m.sandbox.paypal.com/v1/oauth2/token"
|
||||||
|
validation_url_prod = "https://api-m.paypal.com/v1/oauth2/token"
|
||||||
|
|
||||||
|
# payload for the post request
|
||||||
|
validation_data = {'grant_type': 'client_credentials'}
|
||||||
|
|
||||||
|
# pass the request
|
||||||
|
validation_response = requests.post(
|
||||||
|
url=validation_url,
|
||||||
|
data=validation_data,
|
||||||
|
auth=(username, password)
|
||||||
|
)
|
||||||
|
|
||||||
|
# todo check status code + try except. Status code 201 ?
|
||||||
|
print(validation_response.text)
|
||||||
|
access_token = json.loads(validation_response.text)["access_token"]
|
||||||
|
|
||||||
|
|
||||||
|
######## STEP 2: Create Order ########
|
||||||
|
# url for post request
|
||||||
|
order_url = "https://api-m.sandbox.paypal.com/v2/checkout/orders"
|
||||||
|
order_url_prod = "https://api-m.paypal.com/v2/checkout/orders"
|
||||||
|
|
||||||
|
# payload for the request
|
||||||
|
order_data = {
|
||||||
|
"intent": "CAPTURE",
|
||||||
|
"purchase_units": [
|
||||||
|
{
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "AnyWay Credits",
|
||||||
|
"description": "50 pack of credits",
|
||||||
|
"quantity": 1,
|
||||||
|
"unit_amount": {
|
||||||
|
"currency_code": "CHF",
|
||||||
|
"value": "5.00"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"amount": {
|
||||||
|
"currency_code": "CHF",
|
||||||
|
"value": "5.00",
|
||||||
|
"breakdown": {
|
||||||
|
"item_total": {
|
||||||
|
"currency_code": "CHF",
|
||||||
|
"value": "5.00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"application_context": {
|
||||||
|
"return_url": "https://anydev.info",
|
||||||
|
"cancel_url": "https://anydev.info"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
order_response = requests.post(
|
||||||
|
url=order_url,
|
||||||
|
json=order_data,
|
||||||
|
auth=(username, password)
|
||||||
|
)
|
||||||
|
|
||||||
|
# todo check status code + try except
|
||||||
|
print(order_response.text)
|
||||||
|
order_id = json.loads(order_response.text)["id"]
|
||||||
|
|
||||||
|
|
||||||
|
######## STEP 3: capture payment
|
||||||
|
# url for post request
|
||||||
|
capture_url = f"https://api-m.sandbox.paypal.com/v2/checkout/orders/{order_id}/capture"
|
||||||
|
capture_url_prod = f"https://api-m.paypal.com/v2/checkout/orders/{order_id}/capture"
|
||||||
|
|
||||||
|
capture_response = requests.post(
|
||||||
|
url=capture_url,
|
||||||
|
json={},
|
||||||
|
auth=(username, password)
|
||||||
|
)
|
||||||
|
|
||||||
|
# todo check status code + try except
|
||||||
|
print(capture_response.text)
|
||||||
|
# order_id = json.loads(response.text)["id"]
|
||||||
|
|
Reference in New Issue
Block a user