RazorPay Payment Gateway Integration in Oracle APEX







  1. Here is the proper explanation of the flow of Razorpay payment checkout from payment start to end in Oracle Apex: 1. User Interaction: The payment process begins when the user manually enters the amount they want to pay on the page. In an application, the amount can be dynamically collected from a service or a product being sold in website . The entered amount is then inserted into a page item. 2. Clicking the Checkout Button: After entering the amount, the user clicks on the "Pay Now" or "Checkout" button to initiate the payment process. 3. Dynamic Action: Once the checkout button is clicked, a dynamic action is triggered. 4. Variable Initialization: The dynamic action initializes all the necessary values into variables. In payment gateways like Razorpay, the currency amount needs to be converted into the base currency (e.g., converting rupees to paisa). The necessary calculations are performed and stored in the variables. 5. Calling Razorpay API: A procedure, likely named "Update Razorpay Response," is used to pass the calculated amount to the API provided by Razorpay. This procedure initiates the API call with the provided username and password for the specific business account (or demo account, if applicable). 6. Receiving the Response: Upon successful completion of the API call, Razorpay returns a response that includes an order ID in the form of a string. 7. Saving the Response: The returned order ID is extracted from the response and inserted into a table named "Razorpay Response." 8. Fetching the Latest Order ID: From the "Razorpay Response" table, the latest order ID is fetched. The method used to fetch the latest or unique order ID may vary based on your requirements. 9. Storing the Order ID: The fetched order ID is inserted into a page item to make it accessible for the subsequent steps. 10. Using Razorpay's Predefined HTML Code: Razorpay provides a predefined HTML code, typically known as Razorpay Payment Form, which facilitates the payment process. In this form, the previously obtained order ID is passed along with other required information. 11. Initiating the Transaction: When the predefined Razorpay Payment Form is displayed, it opens a popup or a form where users can enter their payment details and complete the transaction.

Prerequisites for Razorpay Integration

Before integrating Razorpay's payment gateway into your system, there are certain prerequisites that need to be fulfilled. These steps ensure a smooth integration process and successful utilization of Razorpay's services. Here's what you need

Account Verification: Ensure that your personal or business account is fully verified with all the necessary documents. This verification process might take anywhere from 2 weeks to 1 month to complete

Client ID and Secret Key: You will require a Client ID and Secret Key from Razorpay to authenticate your integration with their services. These keys serve as credentials to securely connect your system with Razorpay's API.

All the required information, including your Client ID and Secret Key, can be found within the API settings of your Razorpay account. This section is typically located within your Razorpay dashboard, where you manage your account settings and configurations.

By meeting these prerequisites, you'll be well-prepared to seamlessly integrate Razorpay's payment gateway into your application and begin accepting payments effectively.

Step 1: Initialize Order ID

In the backend PL/SQL code, initialize the order ID for the payment using the following SQL code:

sql
SELECT NVL((MAX(VC_ORDER_NO)), 0) + 1 INTO :P2_ORDER_ID FROM RAZORPAY_RESPONSE;

Step 2: Create Payment Component

  1. Create a payment component with the following details:

    • Name: Payment
    • Card No: 5267 XXXX XXXX XXXX
    • Expiry: 11/29
    • CVV: 111

Step 3: Create Page Items

  1. Create two page items to store the order details:

    • P2_ORDER_ID: Stores the order ID generated in Step 1.
    • P2_AMOUNT_PAY: Stores the amount to be paid by the user.

Step 4: Create "Pay" Button with Dynamic Action

  1. Create a button on the page, labeled "Pay."
  2. Set up a dynamic action on the button to trigger a server-side process when clicked.

Step 5: Server-Side Process to Generate Payment

Implement the first server-side process using PL/SQL to generate the payment with Razorpay. Use the provided procedure "UPDATED_RAZORPAY_RESPONSE" to create the payment order. Example code:

sql
DECLARE x VARCHAR2(100); z VARCHAR2(100); BEGIN x := :P2_AMOUNT_PAY; z := x * 100; UPDATED_RAZORPAY_RESPONSE(z); END;

Step 6: Server-Side Process to Retrieve Payment ID

Implement the second server-side process using PL/SQL to retrieve the payment ID from the Razorpay API. Example code:

sql
BEGIN SELECT MAX(ID) INTO :P2_GET_ID FROM RAZORPAY_RESPONSE; END;

Step 7: JavaScript Code for Payment ID Retrieval

  1. Add the following JavaScript code on the page to retrieve the payment ID and store it in the page item "P2_GET_ID":
javascript
$("#button1").click();

Step 8: Create Page Item for Payment ID

Create a page item, "P2_GET_ID," to store the retrieved payment ID.

Step 9: Create Subregion for Payment Response Content

Create a subregion with the name "Content" to display the payment response details

<html> <body> <!-- Razorpay Payment Button --> <!-- <button id="rzp-button1">Razorpay Button</button> --> <script src="https://checkout.razorpay.com/v1/checkout.js"></script> <script> // Function to handle the button click event document.getElementById('button1').onclick = function(e) { // Get the value of P2_GET_ID from Apex item var v_id = apex.item('P2_GET_ID').getValue(); // Options for the Razorpay checkout var options = { "key": "rzp_test_heUS3YxZACZhl50qwq", // Your Razorpay test key "amount": "50000", // Amount in paise (e.g., 50000 paise = Rs 500) "name": "ESS CORP", // Name of the payment receiver "description": "Test Transaction", // Description of the payment "order_id": v_id, // Your custom order ID // Handler function to be executed after successful payment "handler": function(response) { // Set values in Apex items for the response data apex.item("P2_PAYMENT_ID_STATUS").setValue(response.razorpay_payment_id); apex.item("P2_ORDER_ID_STATUS").setValue(response.razorpay_order_id); apex.item("P2_SIGNATURE").setValue(response.razorpay_signature); apex.item("P2_TRANSACTION_STATUS").setValue('Transaction Successful'); }, // Pre-filled customer information "prefill": { "name": "Tech Probie", "email": "test@example.com", "contact": "9999999999" }, // Additional notes for the payment "notes": { "address": "Razorpay Corporate Office" }, // Custom theme color for the Razorpay checkout window "theme": { "color": "#3399cc" } }; // Create a new Razorpay instance and open the checkout window var rzp1 = new Razorpay(options); rzp1.on('payment.failed', function(response) { // Handle the case where payment fails // For example, you can show an error message to the user }); rzp1.open(); e.preventDefault(); // Prevent the default button click behavior } </script> </body> </html>


Step 10: Add "Print" Button in Content Subregion

Add a "Print" button within the "Content" subregion to enable users to view the payment response details.

Step 11: Create Page Item for Transaction Status

Create a page item, "P2_TRANSACTION_STATUS," to store the transaction status.

Step 12: Dynamic Action to Update Response Table

Implement a dynamic action on the "P2_TRANSACTION_STATUS" page item to trigger a server-side process when the transaction status changes.

In the server-side process, update the "RAZORPAY_RESPONSE" table with the response details using the provided SQL code:

sql
UPDATE RAZORPAY_RESPONSE SET PAYMENT_ID_STATUS = :P2_PAYMENT_ID_STATUS, ORDER_ID_STATUS = :P2_ORDER_ID_STATUS, SIGNATURE = :P2_SIGNATURE, ORDER_STATUS = 'done' WHERE VC_ORDER_NO = :P2_GET_ID;

Step 13: Create Procedure for Razorpay API Integration

Create or replace the PL/SQL procedure "UPDATED_RAZORPAY_RESPONSE" to integrate with the Razorpay API. This procedure generates the order, sends the payment request, and stores the response data in the "RAZORPAY_RESPONSE" table.

sql
CREATE OR REPLACE PROCEDURE UPDATED_RAZORPAY_RESPONSE( amount_pay IN NUMBER -- Assuming the amount_pay is a numeric value in paisa ) AS l_resp_clob CLOB; l_body_clob CLOB; order_SEQ NUMBER; BEGIN -- Step 1: Input validation IF amount_pay <= 0 THEN RAISE_APPLICATION_ERROR(-20001, 'Invalid amount_pay. The value must be greater than zero.'); END IF; -- Step 2: Generate order sequence SELECT NVL(MAX(VC_ORDER_NO) + 1, 1) INTO order_SEQ FROM RAZORPAY_RESPONSE; -- Step 3: Build the JSON request body l_body_clob := '{"amount": ' || amount_pay || ',"currency": "INR","receipt": "' || order_SEQ || '"}'; -- Step 4: Set up request headers and make REST request to Razorpay API apex_web_service.g_request_headers(1).name := 'Content-Type'; apex_web_service.g_request_headers(1).value := 'application/json'; l_resp_clob := apex_web_service.make_rest_request( p_url => 'https://api.razorpay.com/v1/orders', p_http_method => 'POST', p_username => 'rzp_test_heUS3YxZACZhl889977', p_password => 'kKlfw2Mq8VnPmPpebvuOSj000qwer', p_body => l_body_clob ); -- Step 5: Parsing the JSON response apex_json.parse(l_resp_clob); -- Step 6: Extract the response data DECLARE id VARCHAR2(400); entity VARCHAR2(400); amount NUMBER; amount_paid NUMBER; amount_due NUMBER; currency VARCHAR2(400); receipt VARCHAR2(400); offer_id VARCHAR2(400); status VARCHAR2(400); attempts VARCHAR2(400); created_at NUMBER; BEGIN id := apex_json.get_varchar2(p_path => 'id'); entity := apex_json.get_varchar2(p_path => 'entity'); amount := apex_json.get_number(p_path => 'amount') / 100; -- Assuming 'amount' in the response is in paisa, converting it to rupees amount_paid := apex_json.get_number(p_path => 'amount_paid') / 100; amount_due := apex_json.get_number(p_path => 'amount_due') / 100; currency := apex_json.get_varchar2(p_path => 'currency'); receipt := apex_json.get_varchar2(p_path => 'receipt'); offer_id := apex_json.get_varchar2(p_path => 'offer_id'); status := apex_json.get_varchar2(p_path => 'status'); attempts := apex_json.get_varchar2(p_path => 'attempts'); created_at := TO_DATE('01-JAN-1970', 'DD-MON-YYYY') + (apex_json.get_number(p_path => 'created_at') / 60 / 60 / 24); -- Step 7: Insert the response data into the RAZORPAY_RESPONSE table INSERT INTO RAZORPAY_RESPONSE ( id, entity, amount, amount_paid, amount_due, currency, vc_order_no, offer_id, status, attempts, created_at, PAYMENT_ID_STATUS, ORDER_ID_STATUS, SIGNATURE, ORDER_STATUS ) VALUES ( id, entity, amount, amount_paid, amount_due, currency, receipt, offer_id, status, attempts, created_at, NULL, NULL, NULL, 'Payment Pending' ); END; EXCEPTION WHEN OTHERS THEN -- Step 8: Handle exceptions (log or raise as required) RAISE; END UPDATED_RAZORPAY_RESPONSE; /

RAZORPAY_RESPONSE Table Structure

Below is the structure of the "RAZORPAY_RESPONSE" table used to store payment details:

sql
CREATE TABLE "RAZORPAY_RESPONSE" ( "ID" VARCHAR2(400), "ENTITY" VARCHAR2(400), "AMOUNT" VARCHAR2(400), "AMOUNT_PAID" VARCHAR2(400), "AMOUNT_DUE" VARCHAR2(400), "CURRENCY" VARCHAR2(400), "VC_ORDER_NO" VARCHAR2(400), "OFFER_ID" VARCHAR2(400), "STATUS" VARCHAR2(400), "ATTEMPTS" VARCHAR2(400), "NOTES" VARCHAR2(400), "CREATED_AT" VARCHAR2(400), "PAYMENT_ID_STATUS" VARCHAR2(500), "ORDER_ID_STATUS" VARCHAR2(800), "SIGNATURE" VARCHAR2(800), "ORDER_STATUS" VARCHAR2(100) );

Please make sure to set up the necessary credentials and configurations for the Razorpay API before implementing the integration.

If you need any further assistance, feel free to contact us at Thapliyalravi81@gmail.com. We are happy to help you!

Comments