Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import logging
- import requests
- import time
- from django.utils import timezone
- from django.conf import settings
- from .models import PayPalExtraPayment, PaypalToken
- SUCCESS_STATUS = requests.codes.ok # 200
- UNAUTHORIZED_STATUS = requests.codes.unauthorized # 401
- APPROVED = 'approved'
- env_paypal_param = {
- True: 'sandbox',
- False: 'production'
- }
- logger = logging.getLogger(__name__)
- def create_access_token():
- """ Creating paypal access token.
- Request:
- Url is 'https://api.sandbox.paypal.com/v1/oauth2/token' for sandbox.
- Auth are paypal client id and client secret.
- Response:
- Status and token.
- If status not 200 - write to the 'err' status and error description.
- Return:
- Paypal token and errors.
- More: 'https://developer.paypal.com/docs/integration/direct/make-your-first-call/#get-an-access-token'
- """
- logger.info("Start creating paypal access token")
- paypaltoken = None
- err = None
- # request data
- url = settings.PAYPAL_URL_TOKEN
- auth = (settings.PAYPAL_CLIENT_ID, settings.PAYPAL_SECRET)
- headers = {'Accept': 'application/json', 'Accept-Language': 'en_US'}
- data = "grant_type=client_credentials"
- # get response data
- response = requests.post(url, auth=auth, headers=headers, data=data, timeout=10)
- response_data = response.json()
- # Check response status
- if response.status_code == SUCCESS_STATUS:
- logger.info("Status 200. Start creating paypal access token")
- # Save token to db
- paypaltoken = PaypalToken.objects.create(
- access_token=response_data['access_token'],
- access_token_exp=response_data['expires_in'],
- access_token_type=response_data['token_type'],
- )
- else:
- err = {response_data['error']: response_data['error_description']}
- return paypaltoken, err
- def get_access_token():
- """ Receiving paypal access token(AT). If AT not in DB or AT is expired
- or difference in time is 5 sec - create a request to receive new access token.
- Return:
- Token and errors.
- """
- logger.info("Starting get access paypal token")
- err = None
- # Get last token from db
- token = PaypalToken.objects.last()
- if token is not None:
- logger.debug("Paypal token founded in DB")
- # difference time
- token_created_sec = time.mktime(token.created.timetuple())
- token_total_sec = token_created_sec+token.access_token_exp
- now_sec = time.mktime(timezone.now().timetuple())
- diff_sec = token_total_sec - now_sec
- logger.debug('diff_sec: {}'.format(diff_sec))
- if int(diff_sec) <= 0:
- token, err = create_access_token()
- else:
- token, err = create_access_token()
- return token, err
- def get_payment_response(payment, token):
- """ Check paypal payment from payment id and access token.
- Requests:
- url - 'https://api.sandbox.paypal.com/v1/payments/payment/{payment_id}' from sandbox.
- headers - 'Authorization: <token_type> <access_token>'.
- Response:
- response status and payment data.
- Return:
- response data and errors.
- More: 'https://developer.paypal.com/docs/api/payments/#payment_get'
- """
- url = settings.PAYPAL_URL_PAYMENT + payment.payment_id
- headers = {
- 'Content-Type': 'application/json',
- 'Authorization': '{0} {1}'.format(token.access_token_type, token.access_token)
- }
- # get response data
- response = requests.get(url, headers=headers, timeout=10)
- return response
- def get_payment_data(payment, token):
- """Get payment data
- """
- response_data = None
- err = None
- # request data
- for i in range(3):
- err = None
- response = get_payment_response(payment, token)
- if response.status_code == SUCCESS_STATUS:
- response_data = response.json()
- break
- elif response.status_code == UNAUTHORIZED_STATUS:
- err = {response_data['error']: response_data['error_description']}
- return response_data, err
- def check_payment(payment_state, transactions, order_id):
- """Check validated payment
- Return:
- errors
- """
- err = None
- if payment_state != APPROVED:
- err = {'Check status': 'not approved!'}
- elif int(order_id) != int(transactions['invoice_number']):
- logger.debug('order id not eq transacrion order id!')
- err = {'Check status': 'order id not eq transacrion order id!'}
- return err
- def process_express(request, order):
- """ Payment process through paypal.
- Saving payment to the database.
- Return:
- paypal extra payment and errors
- """
- logger.info('Start process extrapaypall expert')
- err = None
- paypal_extra_payment = None
- data = request.POST
- # Get access token
- token, token_err = get_access_token()
- if token_err:
- logger.info("Get access token has some errors: {}".format(token_err))
- return paypal_extra_payment, token_err
- logger.debug('Token is {}'.format(token))
- # Begin creating a record in the table PayPalExtraPayment
- paypal_extra_payment = PayPalExtraPayment(
- payment_id=data['paymentID'],
- payer_id=data['payerID'],
- payment_token=data['paymentToken'],
- return_url=data['returnUrl'],
- access_token=token,
- payer_ip=request.META.get('HTTP_X_FORWARDED_FOR')
- )
- # Get payment details
- payment_data, payment_err = get_payment_data(paypal_extra_payment, token)
- if payment_err:
- logger.info("Valid has some errors: {}".format(payment_err))
- return paypal_extra_payment, payment_err
- transactions = payment_data['transactions'][0]
- # Check paypal payment
- check_error = check_payment(payment_data['state'], transactions, order.id)
- if check_error:
- logger.info("Valid has some errors: {}".format(payment_err))
- return paypal_extra_payment, check_error
- payer = payment_data['payer']
- related_resources = transactions['related_resources'][0]['sale']
- # Data to DB
- paypal_extra_payment.order = order
- paypal_extra_payment.raw_data = payment_data
- paypal_extra_payment.payment_date = payment_data['create_time']
- paypal_extra_payment.status = payment_data['state']
- paypal_extra_payment.merchant_id = transactions['payee']['merchant_id']
- paypal_extra_payment.invoice_number = transactions['invoice_number']
- paypal_extra_payment.items = transactions['description']
- paypal_extra_payment.currency = transactions['amount']['currency']
- paypal_extra_payment.price_total = transactions['amount']['total']
- paypal_extra_payment.price_subtotal = transactions['amount']['details']['subtotal']
- paypal_extra_payment.price_fee = related_resources['transaction_fee']['value']
- paypal_extra_payment.payer_info = payer['payer_info']
- paypal_extra_payment.payer_first_name = payer['payer_info']['first_name']
- paypal_extra_payment.payer_last_name = payer['payer_info']['last_name']
- paypal_extra_payment.payer_email = payer['payer_info']['email']
- paypal_extra_payment.save()
- logger.info('Paypal extra payment created: {}'.format(paypal_extra_payment))
- return paypal_extra_payment, err
Add Comment
Please, Sign In to add comment