top of page

We are officially abandoning the North iFrame JavaScript SDK approach for this application.

Do not continue any work on:

  • pay-now.min.js

  • hosted fields

  • browser-side tokenization

  • SDK certification pages

  • PayNow, PayNowSdk, getToken(), or any iframe SDK integration attempts

We are implementing North using Custom Pay API instead.

This is the correct path for us because:

  • GiveHub 1.0 has successfully used North Custom Pay API for many years

  • the iFrame SDK effort has been inconsistent, undocumented, and not a productive use of time

  • we already have strong evidence for the correct server-side API pattern

Goal

Build a backend-driven North payment integration using Custom Pay API /sale.

Architecture

Frontend

Build a secure payment form that collects:

  • card number

  • expiration date

  • CVV

  • billing address

  • ZIP

  • first name

  • last name

  • amount

The browser should submit payment data over HTTPS to our backend only.

Backend

Build:
POST /api/north/charge

This endpoint should:

  1. validate incoming payment data

  2. load the correct North config for the organization

  3. construct the North /sale JSON payload

  4. compute epi-signature

  5. send the request server-to-server to North

  6. normalize the response back to frontend

Confirmed North API details

Base URL

From our existing generated API client:

  • base URL defaults to:
    https://epi.epxuap.com

Sale endpoint

Use:

  • POST /sale

This is confirmed in our existing salesApi.ts implementation.

Required headers

Set:

  • Content-Type: application/json

  • EPI-Id: <merchant four-part processing key>

  • EPI-Signature: <HMAC signature>

  • optional EPI-Trace: <merchant trace value>

  • optional EPI-Version: 1.0

Signature generation

North confirms:

  • signature is HMAC-SHA256

  • signed data is the concatenation of:

    1. endpoint path

    2. exact raw JSON payload string

So implement:

epi-signature = HMAC_SHA256(epiKey, "/sale" + JSON.stringify(payload))

Important:

  • sign the endpoint path "/sale" — not the full URL

  • use the exact JSON string sent in the request body

  • do not pretty-print or reformat after signing

  • use lowercase hex output unless North explicitly requires uppercase

Response handling

North responses use:

  • reference

  • data

  • errors

Approvals should be identified by:

  • data.response === "00"

Anything else is decline/failure.

Example approval fields:

  • data.authorization

  • data.response

  • data.text

  • reference.bric

Existing confirmed North client behavior from our reference code

Our existing salesApi.ts confirms:

  • /sale is the auth+capture endpoint

  • headers must include:

    • EPI-Id

    • EPI-Signature

    • Content-Type

    • EPI-Trace optional

  • request body is JSON

  • success is any 2xx HTTP response, but application-level approval still needs to be checked using North’s response code

Please model the new integration after that server-side pattern.

Per-org configuration to store

At minimum, store per organization:

  • epiId

  • epiKey

  • environment

  • baseUrl if environment-specific override is needed

  • any batch/default transaction settings required by North

  • optional trace prefix or terminal config if required

Do not hardcode merchant credentials in frontend code.

Security rules

This is a direct server-side card flow.

Requirements:

  • do not log raw card number

  • do not log CVV

  • do not store raw card data

  • do not persist PAN anywhere

  • do not include PAN/CVV in structured logs, traces, error payloads, or analytics

  • only pass card data through to North for the live transaction request

Allowed logs:

  • org id

  • environment

  • amount

  • last4 only if needed

  • North response code

  • transaction id / BRIC

  • approval/decline result

Frontend request shape

The frontend should POST JSON to our backend like:

{ "orgId": 1, "amount": 25.00, "firstName": "John", "lastName": "Doe", "cardNumber": "4111111111111111", "expirationDate": "1227", "cvv": "123", "address": "123 Main St", "zip": "30062", "email": "john@example.com", "description": "Donation" }

ZIP is required.

Billing address should also be collected and sent if North AVS supports/uses it.

Backend endpoint contract

Build:
POST /api/north/charge

Pseudo-flow:

  1. Validate required fields:

    • orgId

    • amount

    • cardNumber

    • expirationDate

    • cvv

    • zip

    • address if AVS requires it

  2. Load org-specific North config:

    • epiId

    • epiKey

    • environment/baseUrl

  3. Build /sale payload using North field names

  4. Serialize payload exactly once:

    • const rawJson = JSON.stringify(payload)

  5. Compute signature:

    • HMAC_SHA256(epiKey, "/sale" + rawJson)

  6. Send:

  7. Parse response:

    • if data.response === "00" => success

    • otherwise => decline/failure

  8. Return normalized response to frontend

Required implementation files

1) Signature helper

Create a helper similar to:

import crypto from "crypto"; export function generateEpiSignature( endpoint: string, payload: unknown, epiKey: string ): string { const rawJson = JSON.stringify(payload); const toSign = endpoint + rawJson; return crypto.createHmac("sha256", epiKey).update(toSign).digest("hex"); }

2) North charge backend

Build a backend endpoint that:

  • constructs the sale payload

  • computes signature

  • posts to North

  • normalizes the result

Example structure:

const endpoint = "/sale"; const payload = { account: cardNumber, amount, expirationDate, cvv2: cvv, // include correct North transaction fields here // include AVS fields here }; const signature = generateEpiSignature(endpoint, payload, epiKey); const response = await fetch(baseUrl + endpoint, { method: "POST", headers: { "Content-Type": "application/json", "EPI-Id": epiId, "EPI-Signature": signature, "EPI-Trace": `gh-${Date.now()}` }, body: JSON.stringify(payload) });

3) Frontend

Build a simple card form that posts to our backend only.
Do not call North directly from the browser.

Important payload guidance

From North’s examples and notes we know valid field names can include things like:

  • account

  • amount

  • transaction

  • taxAmount

  • taxExempt

Our implementation must use the correct /sale payload shape for ecommerce card-not-present transactions.

Do not guess field names like:

  • industry type

  • card entry method

  • batch id

  • AVS object structure

Use the Custom Pay API spec / legacy reference pattern and confirm the final payload shape before coding.

If needed, mirror the naming used in GiveHub 1.0.

Approval / decline normalization

Return this shape on success:

{ "success": true, "transactionId": "...", "authCode": "...", "message": "Approved" }

Return this shape on failure:

{ "success": false, "error": "...", "message": "Declined or failed" }

Use:

  • data.response === "00" for approval

  • data.authorization for auth code if present

  • reference.bric for transaction reference if present

What not to do

Do not:

  • continue any iframe SDK work

  • use pay-now.min.js

  • build hosted fields

  • use PayNow / PayNowSdk

  • invent new North integration patterns

  • guess signature rules

  • sign the full URL

  • log raw payment data

What I need from you before coding

Reply with a short technical plan that includes:

  1. exact backend endpoint(s) you will create

  2. exact frontend request payload shape

  3. exact North /sale payload shape you will send

  4. exact TypeScript code you will use to generate EPI-Signature

  5. exact sandbox and production base URLs

  6. exact per-org config fields you will store

  7. exact AVS / ZIP validation behavior

  8. exact logging redaction rules

Do not start coding until you provide this implementation plan.

This should be implemented as a straightforward backend Custom Pay API flow, modeled after our proven North server-side pattern, not as a new browser-SDK integration.

Givehub.com

GiveHub.com
Acworth, GA 30101

United States
Email: sales@givehub.com
Phone: 866-933-7048

 

MISSION STATEMENT

 

To offer a robust and a superior product suite to help non-profits and churches increase giving and operate more effectively and efficiently with cutting edge technology. 

 

Yours in Christ, 
GiveHub.com Team

  • Facebook Social Icon
  • LinkedIn Social Icon
  • Instagram Social Icon

© 2026 GiveHub.com - All rights reserved - Support - Book a Demo

bottom of page