Razorpay Payment Gateway Integration — Oracle Apex 20.x

Ref : http://consultit.co.in/

https://razorpay.com/docs/payment-gateway/web-integration/standard

Now a days in first evolving Digital World Payment Gateways are integral part of most of business problems like e-commerce websites making payments for orders, Any online subscription purchase for online platforms.

Recently I came across one Such business problem where users payments need to be carried out from Oracle Apex page.

Those who are new in oracle apex , Oracle apex is a low code oracle platform where Business ready web application can be build with in sort period of time. We are going to show you Razorpay(https://razorpay.com/) payment gateway integration with oracle Apex page.Razorpay has provided sample code in popular programming language.Oracle implementation is not a part of their custom implementation.hence I am writing this story.

Prerequisites

  1. Create oracle apex login -apex.oracle.com and create a sample application with Pay Now button.
  2. Sign up with Razorpay for generating API Key and API Secret.
  3. We will be using Oracle PL/SQL, Oracle Database, Oracle Apex, Razorp

Payment Process Steps

  1. We will be using Hosted Checkout Integration (Payment Data will be managed by Razorpay). For more information please refer to https://razorpay.com/docs/payment-gateway/web-integration/hosted/ this link.
  2. Create Razorpay Order in your server side by Calling razorpay Orders API. Please find the below Sample Code for RazorPay Order Creation and below procedure with Return Order Status,
 PROCEDURE CREATE_RAZPAY_ORDERS(p_amount VARCHAR2,
 x_razpay_order_id OUT VARCHAR2,
 x_razpay_order_status OUT VARCHAR2,
 X_razpay_error_msg OUT VARCHAR2)
IS
L_CODE VARCHAR2(240);
 L_RETURN CLOB;
 L_JSON APEX_JSON.T_VALUES;
 l_razpay_order_id VARCHAR2(240);
 l_razpay_api_key VARCHAR2(240) := v(‘RAZPAY_API_KEY’);
 l_razpay_api_secret VARCHAR2(240) := v(‘RAZPAY_API_SECRET’);
 l_order_currency VARCHAR2(240) := ‘INR’;
 l_final_amount NUMBER := NULL;
BEGIN
 APEX_WEB_SERVICE.G_REQUEST_HEADERS(APEX_WEB_SERVICE.G_REQUEST_HEADERS.COUNT + 1).NAME := ‘Content-Type’;
 APEX_WEB_SERVICE.G_REQUEST_HEADERS(APEX_WEB_SERVICE.G_REQUEST_HEADERS.COUNT).VALUE := ‘application/x-www-form-urlencoded’;
 — dbms_output.put_line(‘p_amount ‘||p_amount);
 — create order
 L_RETURN := APEX_WEB_SERVICE.MAKE_REST_REQUEST(P_URL => ‘https://api.razorpay.com/v1/orders', 
 P_HTTP_METHOD => ‘POST’, 
 P_USERNAME => l_razpay_api_key, — razorpay api key
 p_password => l_razpay_api_secret, — razorpay api secret available in dashboard
 P_PARM_NAME => APEX_UTIL.STRING_TO_TABLE(‘amount:currency:payment_capture’), 
 P_PARM_VALUE => APEX_UTIL.STRING_TO_TABLE(p_amount||’:’||l_order_currency||’:’ || ‘1’));
 
 — dbms_output.put_line(L_RETURN);
 APEX_JSON.PARSE(L_RETURN);
x_razpay_order_id := apex_json.get_varchar2(p_path => ‘id’);
 x_razpay_order_status := apex_json.get_varchar2(p_path => ‘status’);
 
 IF x_razpay_order_id IS NULL THEN
 x_razpay_order_status := ‘Failed’;
 END IF;
 
 X_razpay_error_msg := apex_json.get_varchar2 (p_path => ‘error.description’,p0 => 1);
 
 l_final_amount := p_amount/100;
 
 INSERT INTO QZ_RAZPAY_PAYMENTS_ACTIVITY
 (RAZPAY_ORDER_ID,PAYMENT_AMOUNT,ORDER_STATUS,ORDER_ERROR_DESCRIPTION,OBJECT_VERSION)
 VALUES (x_razpay_order_id,l_final_amount,x_razpay_order_status,X_razpay_error_msg,1);
 COMMIT;
 EXCEPTION WHEN OTHERS THEN
 RAISE_APPLICATION_ERROR (-20101, SQLERRM) ;
END;

3.  Create a Sample Apex Page like below screenshot.

Behind the Submit Button(Pay now) add the below codes

a. Create Dynamic Action in Apex and call above create order procedure by passing order amount.

b. Then add some javascript Code to call Razorpay provided payment Widget then Put your Test Card Number(available in Razorpay Account) for creating Test Transaction.

c. Once Payment is initiated and successful then , razorpay payment id, Signature, Razorpay Order Id which you can store in your database for Further Validation purpose.

var ordid = $v(‘P2_ORDERID’);
var amount = $v(‘P2_AMOUNT’);
var name = $v(‘P2_NAME’);
var email = $v(‘P2_EMAIL’);
var cnumber = $v(‘P2_PHONENUMBER’);
var options = {
 “key”: “<RAZORPAY_API_KEY>”,
 “amount”: amount,
 “currency”: “INR”,
 “name”: “ “,
 “description”: “Test Transaction”,
 “image”: “https://*.com/assets/lib/global/img/logo-final_two-02.png",
 “order_id”: ordid,
 “handler”: function (response){
 console.log(response.razorpay_payment_id);
 console.log(response.razorpay_order_id);
 console.log(response.razorpay_signature)
 },
 “prefill”: {
 “name”: name,
 “email”: email,
 “contact”: cnumber
 },
 “notes”: {
 “address”: “Razorpay Corporate Office”
 },
 “theme”: {
 “color”: “#F37254”
 }
};
var rzp1 = new Razorpay(options);
//document.getElementById(‘SUBMIT’).onclick = function(e){
 rzp1.open();
//}

4. Once Order and Payment got created then same payment id will be created in Razorpay site.you will be able to view this payment details in Razorpay Dashboard.

https://dashboard.razorpay.com/app/payments

5. Now Payment is captured in razorpay. Till now we have received only Payment Id. We need remaining payment information for storing into our data. Lets say if payment got failed due to Bad Request then we need those informations. We will discuss about webhook.

Web hook

https://razorpay.com/docs/razorpayx/api/webhooks

Webhooks allow you to build or set up integrations that subscribe to certain events on Razorpay API. When one of these events is triggered, we send an HTTP POST payload in JSON to the webhook’s configured URL.

You can set up a webhook from your Dashboard. In URLs, currently, only port numbers 80 and 443 are allowed.

When setting up the webhook, you have the option to enter a secret. Using this secret, you can validate that the webhook is from Razorpay. Entering the secret is optional but recommended. The secret should never be exposed anywhere publicly.

For receiving Webhook Payload in we need to create Rest Endpoint in oracle Apex by suning below Screenshot —

Post API Source Code :

declare
 l_blob blob := :body;
 l_clob clob;
 l_dest_offsset integer := 1;
 l_src_offsset integer := 1;
 l_lang_context integer := dbms_lob.default_lang_ctx;
 l_warning integer;
 l_orderId number := 0;
 l_object_version_number number := 0;
 l_razpay_order_id VARCHAR2(100) :=null;
 l_final_amount number := NULL;
 — 
begin
 dbms_lob.createtemporary(l_clob, true);
 — convert binary body to clob
 dbms_lob.converttoclob
 ( dest_lob => l_clob
 , src_blob => l_blob
 , amount => dbms_lob.lobmaxsize
 , dest_offset => l_dest_offsset
 , src_offset => l_src_offsset
 , blob_csid => dbms_lob.default_csid
 , lang_context => l_lang_context
 , warning => l_warning )
 ;
 — store the full body
 — EXECUTE IMMEDIATE ‘TRUNCATE TABLE json_test’;
 
 apex_json.parse (l_clob);
 
 
 INSERT INTO XX_razpay_payment_response(
 razpay_order_id,
 razpay_payment_id,
 webhook_response,
 creation_date
 )
 VALUES (
 apex_json.get_varchar2 (p_path => ‘payload.payment.entity.order_id’,p0 => 1)
 , apex_json.get_varchar2 (p_path => ‘payload.payment.entity.id’,p0 => 1)
 ,l_clob
 ,SYSDATE 
 );
 
 
 — parse expected body to MY_ORDERS
 
 
 /*
 dbms_output.put_line (‘event: ‘ || apex_json.get_varchar2 (p_path => ‘event’,p0 => 1));
 dbms_output.put_line (‘Payment Id: ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.id’,p0 => 1));
 dbms_output.put_line (‘entity: ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.entity’,p0 => 1));
 dbms_output.put_line (‘Payment amount: ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.amount’,p0 => 1));
 dbms_output.put_line (‘Payment currency: ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.currency’,p0 => 1));
 dbms_output.put_line (‘Payment status: ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.status’,p0 => 1));
 dbms_output.put_line (‘Order Id : ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.order_id’,p0 => 1));
 dbms_output.put_line (‘error_code : ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.error_code’,p0 => 1));
 dbms_output.put_line (‘error_description : ‘ || apex_json.get_varchar2 (p_path => ‘payload.payment.entity.error_description’,p0 => 1));
 */
 
 l_razpay_order_id := apex_json.get_varchar2 (p_path => ‘payload.payment.entity.order_id’,p0 => 1);
 
 BEGIN 
 SELECT MAX(OBJECT_VERSION) +1
 INTO l_object_version_number
 FROM XX_RAZPAY_PAYMENTS_ACTIVITY
 WHERE RAZPAY_ORDER_ID = l_razpay_order_id;
 EXCEPTION WHEN OTHERS THEN
 l_object_version_number := 1;
 END;
 
 l_final_amount := NULL;
 
 l_final_amount := TO_NUMBER(apex_json.get_varchar2 (p_path => ‘payload.payment.entity.amount’,p0 => 1))/100;
 
 
 insert into XX_RAZPAY_PAYMENTS_ACTIVITY
 ( RAZPAY_ORDER_ID, RAZPAY_PAYMENT_ID, PAYMENT_STATUS,event,entity,PAYMENT_AMOUNT,PAYMENT_CURRENCY,PAYMENT_DATE,OBJECT_VERSION,
 PAYMENT_ERROR_CODE,PAYMENT_ERROR_DESCRIPTION,last_update_date,ORDER_STATUS)
 values
 ( apex_json.get_varchar2 (p_path => ‘payload.payment.entity.order_id’,p0 => 1)
 , apex_json.get_varchar2 (p_path => ‘payload.payment.entity.id’,p0 => 1)
 , apex_json.get_varchar2 (p_path => ‘payload.payment.entity.status’,p0 => 1)
 ,apex_json.get_varchar2 (p_path => ‘event’,p0 => 1)
 ,apex_json.get_varchar2 (p_path => ‘payload.payment.entity.entity’,p0 => 1)
 ,l_final_amount
 ,apex_json.get_varchar2 (p_path => ‘payload.payment.entity.currency’,p0 => 1)
 ,SYSDATE
 ,l_object_version_number
 ,apex_json.get_varchar2 (p_path => ‘payload.payment.entity.error_code’,p0 => 1)
 ,apex_json.get_varchar2 (p_path => ‘payload.payment.entity.error_description’,p0 => 1)
 ,SYSDATE
 , apex_json.get_varchar2 (p_path => ‘payload.order.entity.status’,p0 => 1)
 );
 
 IF (apex_json.get_varchar2 (p_path => ‘event’,p0 => 1)) = ‘payment.failed’ THEN
 UPDATE XX_PAYMENT 
 SET STATUS = ‘failed’
 WHERE ORDERID = l_razpay_order_id;
 END IF;
 COMMIT;
end;

Add full API Rest API Url in Web hook Configuration.

Then Once Any Event Fired then You will receive response in your Oracle database.

Closing Notes

we have other payment gateway option like Paytm,PayUMoney,Stripe. Process are more or less same. Thank you. If you like please clap.

References

https://razorpay.com

    Leave a Comment

    Your email address will not be published. Required fields are marked *

    Scroll to Top