Integrating PayMongo to your Django Application - carloramferrer/Django-AWS GitHub Wiki
Add a PayMongo Credit Card Payment Gateway
To integrate a PayMongo payment form, you need to setup an account first and take note of your public and private keys. You will need this for simple authentication when making your API calls.
Django Methods
Initialize your public and private keys in your environment settings:
public_key = "---"
private_key = "---"
Create your Payment Intent
You should create your payment intent from your back end using your secret API key then send the client_key of the response to the client-side. This client_key will be used to attach a payment method to the payment intent. In this step, the payment intent's status is awaiting_payment_method.
def PaymentIntent(amount):
url = "https://api.paymongo.com/v1/payment_intents"
payload = "{\"data\":{\"attributes\":{\"payment_method_allowed\":[\"card\"],\"amount\":" + str(amount) + ",\"currency\":\"PHP\"}}}"
headers = {
'accept': "application/json",
'content-type': "application/json",
'authorization': "Basic ____"
}
response = requests.request("POST", url, data=payload, headers=headers)
data = response.json()
print(data)
return data
Setup and Attach your Payment Method
From the client-side, the collected credit card information must be sent to PayMongo by creating a PaymentMethod. Attach it to the Payment Intent using the client_key as the Payment Intent identifier and your public API key for authentication. For better user experience, an asynchronous call is highly recommended to lessen page redirection.
def PaymentMethod(cardnum, exp_month, exp_year, cvc):
url = "https://api.paymongo.com/v1/payment_methods"
payload = "{\"data\":{\"attributes\":{\"details\":{\"card_number\":\""+ str(cardnum) + "\",\"exp_month\":" + str(exp_month) + ",\"exp_year\":" + str(exp_year) + ",\"cvc\":\"" + str(cvc) + "\"},\"type\":\"card\"}}}"
headers = {
'accept': "application/json",
'content-type': "application/json",
'authorization': "Basic ___"
}
response = requests.request("POST", url, data=payload, headers=headers)
data = response.json()
print(data)
return data
def AttachPaymentMethod(pi, pm):
url = "https://api.paymongo.com/v1/payment_intents/" + str(pi) + "/attach"
payload = "{\"data\":{\"attributes\":{\"payment_method\":\"" + str(pm) + "\"}}}"
headers = {
'accept': "application/json",
'content-type': "application/json",
'authorization': "Basic ___"
}
response = requests.request("POST", url, data=payload, headers=headers)
data = response.json()
print(data)
return data
Paymongo Payment Page Sample
Create a checkout page that accepts payments and updates your booking details. After a POST method is called, you shall call your methods to generate a payment method and attach this to the intent to fulfill the payment. Make sure to note all errors and issues during payment processing.
def PayTransaction(request,id):
status = "Pending"
try:
booking = Booking.objects.get(id = id)
if booking.status == "Successful":
status = "Successful"
except(TypeError, ValueError, OverflowError, Booking.DoesNotExist):
booking = None
if request.method == "POST":
name = request.POST.get('name','')
cardnum = int(request.POST.get('cardnum',''))
month = int(request.POST.get('month',''))
year = int(request.POST.get('year',''))
cvv = int(request.POST.get('cvv',''))
# Create payment intent
intent = PaymentIntent(int(booking.price*100))
pi = intent['data']['id']
try:
intent_errors = intent['errors'][0]['detail']
booking.notes = booking.notes + " \n Error: " + str(intent_errors)
return redirect('landing',int(booking.id), 'Unsuccessful')
except:
# Create payment method
method = PaymentMethod(cardnum, month, year, cvv)
try :
method_errors = method['errors'][0]['detail']
booking.notes = booking.notes + " \n Error: " + str(method_errors)
return redirect('landing',int(booking.id), 'Unsuccessful')
except:
pm = method['data']['id']
attach = AttachPaymentMethod(pi,pm)
try:
errors = attach['errors'][0]['detail']
booking.notes = booking.notes + " \n Error: " + str(errors)
booking.save()
return redirect('landing',int(booking.id), 'Unsuccessful')
except:
status = attach['data']['attributes']['status']
payment_status = attach['data']['attributes']['payments'][0]['attributes']['status']
if status == "succeeded" and payment_status == 'paid':
return redirect('landing', int(booking.id), 'Success')
else:
return redirect('pay',(int(booking.id)))
context = {
'status':status,
'booking':booking,
}
return render(request, 'checkout.html', context)