Payment Integration Tutorial for Webmasters

Accept all card payments on your website

Add this handsom iframe into your website. It will load your payment gateway page securely from Chingup. With this interface you will be able to accept Visa, Mastercard, American Express, Discover as well as the Chingup Card.

Please read about our amazing processing rates.

Add this code to your web page

Below is the complete code to integrate Chingup payments into your website:

Instructions:
1. Copy and paste the code into your page or code.
2. Replace the following with your unique credentials and sale details:

    - amount
    - merchant_id
    - transaction_id

This code creates a secure iframe loading the Chingup payment page.


<body>

<!-- Chingup Payment Iframe -->
<iframe id="payment_iframe" src="https://chingup.com/card_payment/"
	style="width:100%; height:420px;" frameborder="0"></iframe>

</body>

<script>
	// JavaScript to handle payment iframe communication
	const iframe = document.getElementById('payment_iframe');
	let paymentDataSent = false;

	// Prepare JSON payload (paymentData) for the iframe
	var paymentData = {
		amount: 10.23,
		merchant_id: '3023d9618e722844c74c33fcad28f130', // Set Your merchant ID
		type: "paymentData",
		transaction_id: "2d5491c573a96002" // Unique transaction ID
	};
	
	// Send amount and merchant_id to the iframe
	function sendPaymentData() {
		if (iframe?.contentWindow && !paymentDataSent) {
			iframe.contentWindow.postMessage(paymentData, "*");
			paymentDataSent = true;
			console.log("[parent] Sent paymentData to iframe");
		} else {
			console.warn("[parent] Iframe not ready or already sent");
		}
	}
	
	iframe.onload = function() {
		// Small delay ensures iframe.contentWindow is ready for iOS Safari etc.
		setTimeout(sendPaymentData, 50);
	};

	// Listen for iframe ping for resend data request
	window.addEventListener("message", function(event) {
		// If the data was sent too quickly while iframe was still being loaded, let's resend it
		if (event.data?.type === "iframePing") {
			console.log("[parent] Iframe ping received β€” resending paymentData");
			sendPaymentData();
			return;
		}

		console.log("Message received from iframe:", event.data);

		// Handle payment result
		const response = event.data;
		if (response && typeof response === 'object' && 'success' in response) {
			if (response.success) {
				alert(`Payment processed successfully!\nApproval Message: ${response.approval_message}`);
			} else {
				let errorMsg = `Payment failed.\nMessage: ${response.message}\nErrors: ${JSON.stringify(response.errors) || "No additional errors."}`;
				alert(errorMsg);
			}
		}
	});
</script>

To obtain your merchant_id for replacing the merchant_id in the code above:

    1. Login or setup an account on Chingup.com.
    2. When logged in, click on the side navigation (three line icon)
    3. Follow these instructions to become a Merchant.
    4. After signingup as a merchant, and when logged in, click on the side navigation (three line icon)
    5. Select »Merchant Preferences and notice your merchant_id under the Card Processing section.


Now lets look at the various parts of the code.

Part 1: The iframe code

Below is the code that creates an iframe that will load the payment gateway page securely from Chingup.


<body>

    <iframe id="payment_iframe" src="https://chingup.com/card_payment/" 
        style="width:100%; height:420px;" frameborder="0"></iframe>

</body>

Part 2a: Send Payment Data to the Iframe

Part of loading the iframe is to send the payment amount, merchant_id and the transaction_id to the iframe using the following JavaScript code. Note: Please replace the example credentials with your actual credentials (see below how to get them) and set the amount as per transaction(s). Also your website should generate a transaction_id and pass it along in each new transaction (it should be unique in your system for later references). We recommend the transaction_id be a 16 digit hexadecimal string:


<script>
	const iframe = document.getElementById('payment_iframe');
	let paymentDataSent = false;

	// Prepare payment data
	const paymentData = {
		amount: 10.23,
		merchant_id: '3023d9618e722844c74c33fcad28f130',
		type: "paymentData",
		transaction_id: "2d5491c573a96002"
	};

	// Send amount and merchant_id to the iframe
	function sendPaymentData() {
		if (iframe?.contentWindow && !paymentDataSent) {
			iframe.contentWindow.postMessage(paymentData, "*");
			paymentDataSent = true;
			console.log("[parent] Sent paymentData to iframe");
		} else {
			console.warn("[parent] Iframe not ready or already sent");
		}
	}

	iframe.onload = function() {
		// Small delay ensures iframe.contentWindow is ready (for iOS Safari etc.)
		setTimeout(sendPaymentData, 50);
	};

	window.addEventListener("message", function (event) {
		if (event.data?.type === "iframePing") {
			console.log("[parent] Iframe ping received");

			if (lastPaymentData && iframe?.contentWindow) {
				console.log("[parent] Resending last paymentData to iframe");
				iframe.contentWindow.postMessage(lastPaymentData, "*");
			}
			return;
		}

		// Handle payment result
		const response = event.data;
		if (response && typeof response === 'object' && 'success' in response) {
			if (response.success) {
				alert(`Payment processed successfully!\nApproval Message: ${response.approval_message}`);
			} else {
				let errorMsg = `Payment failed.\nMessage: ${response.message}\nErrors: ${JSON.stringify(response.errors) || "No additional errors."}`;
				alert(errorMsg);
			}
		}
	});
</script>

Part 2b: Send Payment Data to the Iframe using buttons

Here are three different button examples. These may be coded for specfic prices.
Notice that the second button has a transaction_id that is passed to the function. This needs to be generated and stored by your website code. As an option, a random transaction_id can be generated in the function as indicated. Ovbiously there are a number of ways to implement this. As always Chingup tech support will help.


<body>
    <!-- The amount is encoded in the button -->
    <button onclick="loadIframe(10.99)">Pay $10.99</button>
    
    <!-- The amount and transaction_id are encoded in the button -->
    <button onclick="loadIframe(29.99, '32ty41934uv776dx')">Pay $29.99</button>
    
    <!-- The amount and transaction_id are passed dynamically (PHP example) -->
    <button onclick="loadIframe(<?php echo $amount ?>, '<?php echo $txn_id ?>')">Pay $<?php echo $amount ?></button>
</body>
  
If you use these buttons you must change the iframe loader in the following way.


<script>
	const iframe = document.getElementById('payment_iframe');
	let lastPaymentData = null;

	// Helper to generate a unique transaction ID (optional fallback)
	function generateTransactionId() {
		return Math.random().toString(16).substr(2, 16);
	}

	// Call this function when a button is clicked
	function loadIframe(amount, transaction_id = null) {
		transaction_id = transaction_id || generateTransactionId();

		lastPaymentData = {
			amount: amount,
			merchant_id: '3023d9618e722844c74c33fcad28f130', // Replace with your merchant_id
			type: "paymentData",
			transaction_id: transaction_id
		};

		// Attempt to send
		if (iframe?.contentWindow) {
			iframe.contentWindow.postMessage(lastPaymentData, "*");
			console.log("[parent] Sent paymentData to iframe");
		} else {
			console.warn("[parent] Iframe not ready to receive paymentData");
		}
	}

	// Listen for iframePing
	window.addEventListener("message", function (event) {
		if (event.data?.type === "iframePing") {
			console.log("[parent] iframePing received β€” resending last paymentData");
			if (lastPaymentData && iframe?.contentWindow) {
				iframe.contentWindow.postMessage(lastPaymentData, "*");
			}
			return;
		}
	});
</script>

Part 3: Listen for Payment Response

Once the payment process is complete, the payment iframe will send back a response. Use this script to listen for the response.
Note: this sucess or failure response is for the customer who just used their card. To be sure that a transaction was successful before you ship product, you need to use the 'Verify Transaction API' below.


<script>
	window.addEventListener("message", function (event) {
		// Handle iframe payment result
		const response = event.data;
		if (response && typeof response === 'object' && 'success' in response) {
			if (response.success) {
				alert("Payment processed successfully!\\nApproval Message: " + response.approval_message);
			} else {
				let errorMsg = "Payment failed.\\nMessage: " + response.message + "\\nErrors: " + (JSON.stringify(response.errors) || "No additional errors.");
				alert(errorMsg);
			}
		}
	});
</script>

Verify the transaction with API

Before initiating a transaction, it’s recommended to generate and store a unique transaction_id on the backend, typically in the session or database. This transaction_id is used to identify the transaction and verify it with Chingup after the payment is complete, ensuring accurate transaction tracking before proceeding with the order fulfillment (e.g., dispatching the product). Below are a few code samples.

To securely interact with the Chingup API and retrieve transaction details, you must provide the api_key.
You can obtain your api_key by:

  1. Logging into Chingup.com
  2. Clicking on the side navigation menu (the three-line icon).
  3. Selecting » Merchant Preferences.
Your merchant_id and api_key can be found under the Card Processing section.


<?php
$url = 'https://chingup.com/api/verify_transaction.php';

$data = [
    'merchant_id'=> '3023d9618e722844c74c33fcad28f130',
    'ref_number' => '000011112', // Ref number that you received from iframe
    'transaction_id' => '2d5491c573a96002',
    'api_key' => 'MERCHANT_UNIQUE_API_KEY'
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$responseData = json_decode($response, true);
if ($responseData['status'] == 'success') {
    // Transaction verified at chingup
    // Do your backend logic here (We just print the response in this example)
    print_r($responseData['data']);
} else {
    // Transaction could not be verified
    echo "Error: " . $responseData['message'];
}
?>

#!/bin/bash

url="https://chingup.com/api/verify_transaction.php"

# ref_number that you received from the iframe.
data="merchant_id=d97723bbe858042c22c8b979a2f28aa1&transaction_id=2d5491c573a96002&ref_number=000011112&api_key=MERCHANT_UNIQUE_API_KEY"

response=$(curl -s -X POST -d "$data" "$url")

# The jq utility is used here to parse JSON in Bash.
# Install it with sudo apt-get install jq or brew install jq if it’s not already installed.
status=$(echo "$response" | jq -r '.status')
if [ "$status" = "success" ]; then
    echo "$response" | jq '.data'
else
    message=$(echo "$response" | jq -r '.message')
    echo "Error: $message"
fi

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<script>
    const url = 'https://chingup.com/api/verify_transaction.php';

    const data = {
        merchant_id: '3023d9618e722844c74c33fcad28f130',
        ref_number: '000011112', // Ref number that you received from iframe
        transaction_id: '2d5491c573a96002',
        api_key: 'MERCHANT_UNIQUE_API_KEY'
    };

    axios.post(url, new URLSearchParams(data))
        .then(response => {
            const responseData = response.data;
            if (responseData.status === 'success') {
                // Do your backend logic here (We just console print the response in this example)
                console.log(responseData.data);
            } else {
                console.log("Error:", responseData.message);
            }
        })
        .catch(error => {
            console.error("Request failed:", error.message);
        });
</script>

import requests

url = 'https://chingup.com/api/verify_transaction.php'
data = {
    'merchant_id': '3023d9618e722844c74c33fcad28f130',
    'ref_number': '000011112', # Ref number that you received from iframe
    'transaction_id': '2d5491c573a96002',
    'api_key': 'MERCHANT_UNIQUE_API_KEY'
}

response = requests.post(url, data=data)
response_data = response.json()

if response_data.get('status') == 'success':
    print(response_data['data'])
else:
    print("Error:", response_data.get('message'))