Skip to content

Commit

Permalink
fix(backend/frontend): change payment flow (#70)
Browse files Browse the repository at this point in the history
* feat: removed verify API and changed callback page flow

* fix(backend): change payment flow

* fix: rollback unwanted changes

* fix(backend): redirect after payment verification

---------

Co-authored-by: Alireza <[email protected]>
  • Loading branch information
Adibov and AlirezaYousefpourM authored Dec 15, 2023
1 parent 79a51d5 commit 4d036c1
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 66 deletions.
13 changes: 5 additions & 8 deletions backend/backend_api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import datetime
import os
import urllib.parse

from django.core.exceptions import ObjectDoesNotExist, ValidationError
Expand Down Expand Up @@ -220,9 +219,6 @@ def payment(self, request):
except ObjectDoesNotExist:
return Response(new_detailed_response(
status.HTTP_400_BAD_REQUEST, "User not found"))
call_back = request.data.get('call_back')
if call_back is None:
return Response(new_detailed_response(status.HTTP_400_BAD_REQUEST, "call_back field is required"))
discount = None
discount_code = request.data.get('discount_code')
if discount_code is not None:
Expand All @@ -238,7 +234,7 @@ def payment(self, request):
payment = Payment.create_payment_for_user(user, discount)
response = ZIFYRequest().create_payment(str(payment.pk), payment.discounted_amount, user.name,
user.phone_number,
user.account.email, call_back)
user.account.email)
if response['status'] == ZIFY_STATUS_OK:
payment.track_id = response['data']['order']
payment.save()
Expand All @@ -262,11 +258,12 @@ def verify(self, request):
response = ZIFYRequest().verify_payment(payment.track_id)
if response['status'] == ZIFY_STATUS_OK:
payment.update_payment_status(Payment.PaymentStatus.PAYMENT_CONFIRMED)
return Response(new_detailed_response(status.HTTP_200_OK, "Payment verified successfully", payment.pk))
return redirect(urllib.parse.urljoin(BASE_URL, 'callback') + '?client_ref_id=' + str(
payment.pk) + '&payment_status=succeeded')
else:
payment.update_payment_status(Payment.PaymentStatus.PAYMENT_REJECTED)
return Response(
new_detailed_response(response['status'], response["message"], payment.pk))
return redirect(urllib.parse.urljoin(BASE_URL, 'callback') + '?client_ref_id=' + str(
payment.pk) + '&payment_status=failed')


class StaffViewSet(viewsets.GenericViewSet,
Expand Down
5 changes: 3 additions & 2 deletions backend/payment_backends/zify.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
ZIFY_URL = "https://zify.ir/api/order/v2/create"
ZIFY_URL_VERIFY = "https://zify.ir/api/order/v2/verify"
ZIFY_PAYMENT_LINK = 'https://zify.ir/order/accept/{track_id}'
ZIFY_CALLBACK = 'https://aaiss.ir/api/payment/verify'


class ZIFYRequest:
Expand All @@ -29,7 +30,7 @@ def __init__(self):
def get_order_url(track_id: str):
return ZIFY_PAYMENT_LINK.format(track_id=track_id)

def create_payment(self, order_id, amount, user_name, user_phone, user_email, call_back):
def create_payment(self, order_id, amount, user_name, user_phone, user_email):
body = {
"payer": {
"first_name": "",
Expand All @@ -53,7 +54,7 @@ def create_payment(self, order_id, amount, user_name, user_phone, user_email, ca
"description": ZIFY_PAYMENT_DESCRIPTION
}
],
"returnUrl": call_back,
"returnUrl": ZIFY_CALLBACK,
"clientRefId": order_id,
"shipping_total": 0,
"off_total": 0,
Expand Down
107 changes: 51 additions & 56 deletions frontend/src/pages/payment-callback/usePaymentCallbackPage.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,55 @@
import { useEffect, useState } from 'react';
import { useAPI } from '../../providers/APIProvider/APIProvider';
import { useConfig } from '../../providers/config-provider/ConfigProvider';
import {useEffect, useState} from 'react';
import {useConfig} from '../../providers/config-provider/ConfigProvider';

export default function usePaymentCallbackPage() {
const { routeParams } = useConfig();

const { verifyPaymentData, postVerifyPayment } = useAPI();

const [paymentStatus, setPaymentStatus] = useState(false);
const [paymentResultsData, setPaymentResultsData] = useState();
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
if (routeParams == null) return;

const clientrefid = routeParams['clientrefid'];
if (!clientrefid)
return
postVerifyPayment({
clientrefid,
});
}, [postVerifyPayment, routeParams]);

useEffect(() => {
if (verifyPaymentData == null) return;

const paymentResultTemp = {};
if (verifyPaymentData.status !== 200 || verifyPaymentData.data.status !== 200) {
setPaymentStatus(false);
paymentResultTemp['Message'] = "Payment Failed!"
} else {
paymentResultTemp['Message'] = "Success!"
setPaymentStatus(true);
}

const keyDict = {
message: 'Message',
refid: 'Reference ID',
card_number: 'Credit Card Number',
data: "Reference ID"
const {routeParams} = useConfig();

const [paymentStatus, setPaymentStatus] = useState(false);
const [paymentResultsData, setPaymentResultsData] = useState();
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
if (routeParams == null) return;

const refID = routeParams['client_ref_id'];
const status = routeParams['payment_status']
if (!refID && !status)
return

const keysDict = {
status: "Status",
redID: "Reference ID"
}
const paymentResultTemp = {}

if (status) {
const statusValues = {
succeeded: true,
failed: false,
}

const statusDict = {
true: "Success!",
false: "Failure!"
}

const statusBool = statusValues[status] ?? false
setPaymentStatus(statusBool)
paymentResultTemp[keysDict.status] = statusDict[statusBool]
}

if (refID) {
paymentResultTemp[keysDict.redID] = refID
}

setPaymentResultsData(paymentResultTemp);
setIsLoading(false)
}, [routeParams]);

return {
routeParams,
paymentStatus,
isLoading,
paymentResultsData,
};
const removedKeys = ['status', 'message']
Object.keys(verifyPaymentData.data).forEach((key) => {
if (removedKeys.indexOf(key) > -1)
return
if (key in keyDict) paymentResultTemp[keyDict[key]] = verifyPaymentData.data[key];
else paymentResultTemp[key] = verifyPaymentData.data[key];
});
setPaymentResultsData(paymentResultTemp);
setIsLoading(false)
}, [verifyPaymentData]);

return {
routeParams,
paymentStatus,
isLoading,
paymentResultsData,
};
}

0 comments on commit 4d036c1

Please sign in to comment.