Jetpay Developer Guide
...
Payment iFrame (beta)
Implementation Guide
16 min
implementation guide step 1 configure the api client set up an axios interceptor to handle authentication and base url configuration import axios from "axios"; import { nanoid } from "nanoid"; // configure axios interceptor for jetpay api axios interceptors request use((config) => { config url = !config url? startswith(external api base url) && external api base url ? external api base url + config url config url; config headers authorization = `bearer ${api token}`; config headers\["cache control"] = "no cache"; config headers\["content type"] = "application/json"; return config; }); environment variables access for different environments, access your variables appropriately // node js / server side const api token = process env api token; const external api base url = process env external api base url; const bank account = process env bank account; // vite / client side const api token = import meta env vite api token; const external api base url = import meta env vite external api base url; const bank account = import meta env vite bank account; step 2 create the checkout link function this function orchestrates the entire payment flow by creating a contact, generating a debit, and retrieving the check complete example you can find a complete, real world example in this public project export async function createiframelink(amount string) promise\<string> { try { // generate unique payment intention id const paymentintentionid = `pi ${nanoid(10)}`; // step 1 create contact const { data contact } = await axios put("/contact", { email `${paymentintentionid}@dropin web`, name `${paymentintentionid} webdropin`, tags \["webdropin", paymentintentionid], }); // step 2 create debit transaction const { data debit } = await axios put("/debit", { amount number(amount), to bank account bank account, contact email contact email, contact name contact name, contact id contact identifier, statement "debit created by webdropin", note "debit created by webdropin", }); // step 3 generate checkout url const transactionresponse = await axios post( `/transaction/${debit identifier}/pay debit/url` ); return transactionresponse data url; } catch (error) { console error("failed to create checkout link ", error); throw new error("unable to initialize payment please try again "); } } function parameters parameter type description amount string payment amount (will be converted to number) return value returns a promise\<string> containing the secure checkout url for the iframe step 3 integrate with your payment component use the checkout link function in your react component import { createiframelink } from "@/data/create iframe link"; import { usestate } from "react"; export function paymentcomponent() { const \[iframeurl, setiframeurl] = usestate\<string>(""); const \[loading, setloading] = usestate(false); const \[error, seterror] = usestate\<string>(""); async function handlecheckout(amount string) { try { setloading(true); seterror(""); const url = await createiframelink(amount); setiframeurl(url); } catch (error) { seterror("failed to initialize payment please try again "); console error("checkout failed ", error); } finally { setloading(false); } } return ( \<div classname="payment container"> {loading && \<div>loading payment \</div>} {error && \<div classname="error">{error}\</div>} {iframeurl && ( \<iframe src={iframeurl} width="100%" height="600" frameborder="0" title="jetpay payment" /> )} \<button onclick={() => handlecheckout("100 00")}>pay $100 00\</button> \</div> ); } step 4 advanced configuration custom contact information for known customers, you can provide real contact information export async function createiframelink( amount string, customerinfo? { email string; name string; customerid string; } ) promise\<string> { const paymentintentionid = customerinfo? customerid || `pi ${nanoid(10)}`; const { data contact } = await axios put("/contact", { email customerinfo? email || `${paymentintentionid}@dropin web`, name customerinfo? name || `${paymentintentionid} webdropin`, tags \["webdropin", paymentintentionid], }); // rest of implementation } error handling best practices implement comprehensive error handling export async function createiframelink(amount string) promise\<string> { // validate input if (!amount || isnan(number(amount)) || number(amount) <= 0) { throw new error("invalid amount provided"); } try { // implementation } catch (error) { // log detailed error for debugging console error("payment initialization failed ", { amount, error error message, timestamp new date() toisostring(), }); // provide user friendly error message if (axios isaxioserror(error)) { if (error response? status === 401) { throw new error("authentication failed please check your api token "); } if (error response? status >= 500) { throw new error( "payment service temporarily unavailable please try again " ); } } throw new error("unable to initialize payment please try again "); } } api response examples contact creation response { "identifier" "contact abc123", "email" "pi xyz789\@dropin web", "name" "pi xyz789 webdropin", "tags" \["webdropin", "pi xyz789"], "created at" "2024 01 15t10 30 00z" } debit creation response { "identifier" "debit def456", "amount" 10000, "currency" "usd", "contact id" "contact abc123", "customer surcharge amount" 250, "status" "pending", "created at" "2024 01 15t10 30 05z" } transaction url response { "url" "https //pay jetpay com/transaction/debit def456?token=secure token here", "expires at" "2024 01 15t11 30 05z" } next steps now that you have the core implementation working, learn how to handle payment events and manage fees continue to events and fees docid 0rhmgt137x 8tfpeyjw1i >