Merge modifications for more separate backend functions #69
@@ -13,6 +13,11 @@ load_dotenv(override=True)
|
||||
@dataclass
|
||||
class Environment :
|
||||
|
kscheidecker marked this conversation as resolved
|
||||
|
||||
# Load supabase secrets
|
||||
supabase_url = os.environ['SUPABASE_URL']
|
||||
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
|
||||
import logging
|
||||
|
||||
import requests
|
||||
from ..configuration.environment import Environment
|
||||
|
||||
|
||||
# Model for payment request body
|
||||
class PaymentRequest(BaseModel):
|
||||
@@ -14,13 +17,22 @@ class PaymentRequest(BaseModel):
|
||||
|
||||
|
||||
# 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.logger = logging.getLogger(__name__)
|
||||
self.sandbox = sandbox_mode
|
||||
|
||||
# Only support purchase of credit 'bundles': 10, 50 or 100 credits worth of trip generation
|
||||
def fetch_price(self) -> float:
|
||||
@@ -34,37 +46,40 @@ class PaymentHandler:
|
||||
self.logger.error(f"Unsupported currency: {self.details.currency}")
|
||||
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():
|
||||
self.logger.info("Payment created successfully")
|
||||
self.payment_id = payment.id
|
||||
def validate(self):
|
||||
|
||||
# Get the approval URL and return it for the user to approve
|
||||
for link in payment.links:
|
||||
if link.rel == "approval_url":
|
||||
return link.href
|
||||
else:
|
||||
self.logger.error(f"Failed to create payment: {payment.error}")
|
||||
raise HTTPException(status_code=500, detail="Payment creation failed")
|
||||
if self.sandbox :
|
||||
validation_url = "https://api-m.sandbox.paypal.com/v1/oauth2/token"
|
||||
else :
|
||||
validation_url = "https://api-m.paypal.com/v1/oauth2/token"
|
||||
|
remoll marked this conversation as resolved
Outdated
remoll
commented
Pretty sure that won't work. It should definitely not be hardcoded since the callback will change depending on prod or staging. Pretty sure that won't work. It should definitely not be hardcoded since the callback will change depending on prod or staging.
|
||||
|
||||
# payload for the validation request
|
||||
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
I like this.