Skip to content

Commit d6bc2a3

Browse files
committed
feat: Transaction Processing logic & Wallet linking implementation
1 parent 622ae4f commit d6bc2a3

File tree

2 files changed

+123
-68
lines changed

2 files changed

+123
-68
lines changed

app/api/helpers/payment.py

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from app.api.helpers.utilities import represents_int
1414
from app.models.stripe_authorization import StripeAuthorization
1515
from app.settings import get_settings, Environment
16-
from app.api.helpers.db import safe_query, save_to_db
16+
from app.api.helpers.db import safe_query
1717
from app.models import db
1818
from app.models.order import Order
1919

@@ -206,47 +206,6 @@ def create_payment(order, return_url, cancel_url):
206206
else:
207207
return False, payment.error
208208

209-
@staticmethod
210-
def verify_payment(payment_id, order):
211-
"""
212-
Verify Paypal payment one more time for paying with Paypal in mobile client
213-
"""
214-
try:
215-
payment_server = paypalrestsdk.Payment.find(payment_id)
216-
if payment_server.state != 'approved':
217-
return False, 'Payment has not been approved yet. Status is ' + payment_server.state + '.'
218-
219-
# Get the most recent transaction
220-
transaction = payment_server.transactions[0]
221-
amount_server = transaction.amount.total
222-
currency_server = transaction.amount.currency
223-
sale_state = transaction.related_resources[0].sale.state
224-
225-
if amount_server != order.amount:
226-
return False, 'Payment amount does not match order'
227-
elif currency_server != order.event.payment_currency:
228-
return False, 'Payment currency does not match order'
229-
if sale_state != 'completed':
230-
return False, 'Sale not completed'
231-
elif PayPalPaymentsManager.used_payment(payment_id, order):
232-
return False, 'Payment already been verified'
233-
else:
234-
return True, None
235-
except paypalrestsdk.ResourceNotFound:
236-
return False, 'Payment Not Found'
237-
238-
@staticmethod
239-
def used_payment(payment_id, order):
240-
"""
241-
Function to check for recycling of payment IDs
242-
"""
243-
if Order.query.filter(Order.paypal_token == payment_id).first() is None:
244-
order.paypal_token = payment_id
245-
save_to_db(order)
246-
return False
247-
else:
248-
return True
249-
250209
@staticmethod
251210
def execute_payment(paypal_payer_id, paypal_payment_id):
252211
"""
@@ -324,10 +283,27 @@ class PaytmPaymentsManager(object):
324283
Class to manage PayTM payments
325284
"""
326285

286+
@property
287+
def paytm_endpoint(self):
288+
if get_settings()['paytm_mode'] == 'test':
289+
url = "https://securegw-stage.paytm.in/theia/api/v1/"
290+
else:
291+
url = "https://securegw.paytm.in/theia/api/v1/"
292+
return url
293+
327294
@staticmethod
328295
def generate_checksum(paytm_params):
329-
if get_settings()['paytm_mode'] == 'sandbox':
296+
if get_settings()['paytm_mode'] == 'test':
330297
merchant_key = get_settings()['paytm_sandbox_secret']
331298
else:
332299
merchant_key = get_settings()['paytm_live_secret']
333300
return checksum.generate_checksum_by_str(json.dumps(paytm_params["body"]), merchant_key)
301+
302+
@staticmethod
303+
def hit_paytm_endpoint(url, head, body=None):
304+
paytm_params = {}
305+
paytm_params["body"] = body
306+
paytm_params["head"] = head
307+
post_data = json.dumps(paytm_params)
308+
response = requests.post(url, data=post_data, headers={"Content-type": "application/json"}).json()
309+
return response

app/api/orders.py

Lines changed: 104 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import logging
22
import json
33
import pytz
4-
from datetime import datetime
4+
import time
5+
import omise
56
import requests
67

7-
8-
import omise
8+
from datetime import datetime
99
from flask import request, jsonify, Blueprint, url_for, redirect
1010
from flask_jwt_extended import current_user
1111
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
@@ -41,6 +41,7 @@
4141
from app.models.ticket_holder import TicketHolder
4242
from app.models.user import User
4343

44+
4445
order_misc_routes = Blueprint('order_misc', __name__, url_prefix='/v1')
4546
alipay_blueprint = Blueprint('alipay_blueprint', __name__, url_prefix='/v1/alipay')
4647

@@ -544,22 +545,6 @@ def create_paypal_payment(order_identifier):
544545
return jsonify(status=False, error=response)
545546

546547

547-
@order_misc_routes.route('/orders/<string:order_identifier>/verify-mobile-paypal-payment', methods=['POST'])
548-
@jwt_required
549-
def verify_mobile_paypal_payment(order_identifier):
550-
"""
551-
Verify paypal payment made on mobile client
552-
:return: The status of order verification
553-
"""
554-
try:
555-
payment_id = request.json['data']['attributes']['payment-id']
556-
except TypeError:
557-
return BadRequestError({'source': ''}, 'Bad Request Error').respond()
558-
order = safe_query(db, Order, 'identifier', order_identifier, 'identifier')
559-
status, error = PayPalPaymentsManager.verify_payment(payment_id, order)
560-
return jsonify(status=status, error=error)
561-
562-
563548
@alipay_blueprint.route('/create_source/<string:order_identifier>', methods=['GET', 'POST'])
564549
def create_source(order_identifier):
565550
"""
@@ -641,14 +626,14 @@ def initiate_transaction(order_identifier):
641626
# body parameters
642627
paytm_params["body"] = {
643628
"requestType": "Payment",
644-
"mid": (get_settings()['paytm_sandbox_merchant'] if paytm_mode == 'sandbox'
629+
"mid": (get_settings()['paytm_sandbox_merchant'] if paytm_mode == 'test'
645630
else get_settings()['paytm_live_merchant']),
646631
"websiteName": "eventyay",
647-
"orderId": order.id,
632+
"orderId": order_identifier,
648633
"callbackUrl": "",
649634
"txnAmount": {
650635
"value": order.amount,
651-
"currency": order.event.payment_currency,
636+
"currency": "INR",
652637
},
653638
"userInfo": {
654639
"custId": order.user.id,
@@ -660,11 +645,105 @@ def initiate_transaction(order_identifier):
660645
"signature" : checksum
661646
}
662647
post_data = json.dumps(paytm_params)
663-
if paytm_mode == 'sandbox':
648+
if paytm_mode == 'test':
664649
url = "https://securegw-stage.paytm.in/theia/api/v1/initiateTransaction?mid={}&orderId={}".\
665-
format(get_settings()['paytm_sandbox_merchant'], order.id)
650+
format(get_settings()['paytm_sandbox_merchant'], order_identifier)
666651
else:
667652
url = "https://securegw.paytm.in/theia/api/v1/initiateTransaction?mid={}&orderId={}".\
668-
format(get_settings()['paytm_sandbox_merchant'], order.id)
653+
format(get_settings()['paytm_live_merchant'], order_identifier)
669654
response = requests.post(url, data=post_data, headers={"Content-type": "application/json"})
670655
return response.json()
656+
657+
658+
@order_misc_routes.route('/orders/<string:order_identifier>/paytm/fetch-payment-options/<string:txn_token>')
659+
def fetch_payment_options(order_identifier, txn_token):
660+
paytm_mode = get_settings()['paytm_mode']
661+
if paytm_mode == 'test':
662+
url = "https://securegw-stage.paytm.in/theia/api/v1/fetchPaymentOptions?mid={}&orderId={}".\
663+
format(get_settings()['paytm_sandbox_merchant'], order_identifier)
664+
else:
665+
url = "https://securegw.paytm.in/theia/api/v1/fetchPaymentOptions?mid={}&orderId={}".\
666+
format(get_settings()['paytm_live_merchant'], order_identifier)
667+
head = {
668+
"clientId": "C11",
669+
"version": "v1",
670+
"requestTimestamp": str(int(time.time())),
671+
"channelId": "WEB",
672+
"txnToken": txn_token
673+
}
674+
response = PaytmPaymentsManager.hit_paytm_endpoint(url=url, head=head)
675+
return response
676+
677+
678+
@order_misc_routes.route('/orders/<string:order_identifier>/paytm/send_otp/<string:txn_token>', methods=['POST', 'GET'])
679+
def send_otp(order_identifier, txn_token):
680+
paytm_mode = get_settings()['paytm_mode']
681+
if paytm_mode == 'test':
682+
url = "https://securegw-stage.paytm.in/theia/api/v1/login/sendOtp?mid={}&orderId={}".\
683+
format(get_settings()['paytm_sandbox_merchant'], order_identifier)
684+
else:
685+
url = "https://securegw.paytm.in/theia/api/v1/login/sendOtp?mid={}&orderId={}".\
686+
format(get_settings()['paytm_live_merchant'], order_identifier)
687+
688+
head = {
689+
"clientId": "C11",
690+
"version": "v1",
691+
"requestTimestamp": str(int(time.time())),
692+
"channelId": "WEB",
693+
"txnToken": txn_token
694+
}
695+
body = {"mobileNumber": ""}
696+
response = PaytmPaymentsManager.hit_paytm_endpoint(url=url, head=head, body=body)
697+
return response
698+
699+
700+
@order_misc_routes.route('/orders/<string:order_identifier>/paytm/validate_otp/<string:txn_token>')
701+
def validate_otp(order_identifier, txn_token):
702+
paytm_mode = get_settings()['paytm_mode']
703+
if paytm_mode == 'test':
704+
url = "https://securegw-stage.paytm.in/theia/api/v1/login/validateOtp?mid={}&orderId={}".\
705+
format(get_settings()['paytm_sandbox_merchant'], order_identifier)
706+
else:
707+
url = "https://securegw.paytm.in/theia/api/v1/login/validateOtp?mid={}&orderId={}".\
708+
format(get_settings()['paytm_live_merchant'], order_identifier)
709+
head = {
710+
"clientId": "C11",
711+
"version": "v1",
712+
"requestTimestamp": str(int(time.time())),
713+
"channelId": "WEB",
714+
"txnToken": txn_token
715+
}
716+
body = {"otp": ""}
717+
response = PaytmPaymentsManager.hit_paytm_endpoint(url=url, head=head, body=body)
718+
return response
719+
720+
721+
@order_misc_routes.route('/orders/<string:order_identifier>/paytm/process_transaction/<string:txn_token>')
722+
def process_transaction(order_identifier, txn_token):
723+
paytm_mode = get_settings()['paytm_mode']
724+
merchant_id = (get_settings()['paytm_sandbox_merchant'] if paytm_mode == 'test'
725+
else get_settings()['paytm_live_merchant'])
726+
727+
if paytm_mode == 'test':
728+
url = "https://securegw-stage.paytm.in/theia/api/v1/processTransaction?mid={}&orderId={}".\
729+
format(get_settings()['paytm_sandbox_merchant'], order_identifier)
730+
else:
731+
url = "https://securegw.paytm.in/theia/api/v1/processTransaction?mid={}&orderId={}".\
732+
format(get_settings()['paytm_live_merchant'], order_identifier)
733+
734+
head = {
735+
"version": "v1",
736+
"requestTimestamp": str(int(time.time())),
737+
"channelId": "WEB",
738+
"txnToken": txn_token
739+
}
740+
741+
body = {
742+
"requestType": "NATIVE",
743+
"mid": merchant_id,
744+
"orderId": order_identifier,
745+
"paymentMode": "BALANCE"
746+
}
747+
748+
response = PaytmPaymentsManager.hit_paytm_endpoint(url=url, head=head, body=body)
749+
return response

0 commit comments

Comments
 (0)