Efrconnection

Install Efrconnection

bench get-app https://github.com/KossamMusundire/EFRCONNECTION

Add the Frappe Gems badge to your README

Maintain Efrconnection? Paste this into your README:

[![Listed on Frappe Gems](https://frappegems.com/api/method/frappe_gems.seo.badge?app=KossamMusundire%2FEFRCONNECTION)](https://frappegems.com/gems/apps/KossamMusundire/EFRCONNECTION)

About Efrconnection

Verifone Card Payments for ERPNext POS

On-site integration gateway plus an ERPNext app. The cashier selects Card; the customer completes the transaction on the Verifone terminal; ERPNext records the payment only after eSocket.POS returns APPROVED.

This project is an integration adapter. It is not a bank, card network, Zimswitch, Postilion, or payment processor.

Use case

I want to integrate ERPNext POS with a vendor-configured Verifone terminal through Postilion eSocket.POS so that when a cashier selects card payment in ERPNext, ERPNext sends the invoice amount to the terminal, the customer completes the card transaction, and the approved/declined result is automatically returned to ERPNext and used to complete or reject the POS payment.

                  ┌─────────────────────────┐
                  │       ERPNext POS       │
                  │                         │
                  │  Create POS Invoice     │
                  │          │              │
                  │          ▼              │
                  │  Select Card Payment    │
                  │          │              │
                  │          ▼              │
                  │  Initiate Payment ─────────────┐
                  │          ▲              │       │
                  │          │              │       │
                  │  Record Payment         │       │
                  └─────────────────────────┘       │
                                                   │
                                                   ▼
                                         ┌──────────────────┐
                                         │ Verifone Gateway  │
                                         └────────┬─────────┘
                                                  │
                                                  ▼
                                         ┌──────────────────┐
                                         │   eSocket.POS    │
                                         └────────┬─────────┘
                                                  │
                                                  ▼
                                         ┌──────────────────┐
                                         │ Verifone Terminal│
                                         │ Insert/Tap + PIN │
                                         └────────┬─────────┘
                                                  │
                                                  ▼
                                             APPROVED
                                                  │
                                                  ▼
                                         ERPNext Payment

Cashier-facing copy is only:

  • Card
  • Please complete payment on terminal
  • Payment approved or Card payment declined. Please try again or select another payment method.

Architecture

Frappe Cloud talks HTTPS to the gateway. The gateway talks TCP/XML to eSocket on the LAN. eSocket's port is never published to the internet.

Frappe Cloud ERPNext  --HTTPS-->  Verifone Gateway (Python)  --TCP/XML-->  eSocket.POS :15000  -->  Verifone

Transaction states

Status Meaning Invoice
CREATED / PROCESSING Terminal is waiting for the customer Unpaid
APPROVED (ResponseCode=00) Bank/switch approved Paid
DECLINED Terminal/switch declined Unpaid; cashier may retry
FAILED Never reached the terminal Unpaid; cashier may retry
UNKNOWN PURCHASE was sent, then the socket dropped or timed out Unpaid, do not retry until reconciled

UNKNOWN exists so a charged customer is never treated as a failed payment.

Audit trail stored per attempt:

POS Invoice → payment_id → eSocket TransactionId → AuthorizationNumber → RRN → status

MVP included

  1. Initiate PURCHASE
  2. Send amount (minor units) and terminal ID
  3. Generate transaction ID (YYYYMMDD + sequence, e.g. 202608250001)
  4. Wait through events such as PROMPT_TRANSACTION_PROCESSING
  5. Parse APPROVE / DECLINE
  6. Return the result to ERPNext
  7. Record payment reference on the POS Invoice only when approved

Not in this version: refunds, reversals, multiple terminals, offline mode, settlement, reconciliation UI, reporting.

1. Run the gateway (on-site PC on the same LAN as eSocket)

cd gateway
python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .env
# Edit .env: GATEWAY_API_KEY, ESOCKET_HOST, ESOCKET_TERMINAL_ID
python app.py

Put HTTPS in front (Caddy, nginx, or Cloudflare Tunnel) and point Frappe Cloud at that URL. The Flask port itself can stay LAN-only.

Dry-run without a terminal:

ESOCKET_MOCK=true
  • Amount 13.13 → DECLINED
  • Amount 99.99 → UNKNOWN
  • Any other amount → APPROVED

2. Install the ERPNext app on Frappe Cloud

Frappe Cloud pulls an app from the root of its Git repository. This repository contains both the app and the on-site gateway, so do not use this monorepo URL as the custom app URL. Publish apps/verifone_pos as its own repository, for example https://github.com//verifone_pos, and push the branch you want Cloud to use.

One way to create that repository while preserving this app's history is:

git subtree split --prefix apps/verifone_pos -b verifone-pos-cloud
git push https://github.com//verifone_pos.git verifone-pos-cloud:main

In Frappe Cloud:

  1. Add the standalone app repository as a custom app.
  2. Select a branch compatible with the Frappe/ERPNext version on the site.
  3. Add the app to the site and deploy.

For a self-hosted bench, the equivalent commands are:

bench get-app https://github.com//verifone_pos.git
bench --site your.site install-app verifone_pos
bench --site your.site migrate

In Verifone Settings:

  • Gateway URL (HTTPS)
  • Gateway API key (same as .env)
  • Terminal ID (CTPTST01 unless the vendor gave you another)
  • Mode of Payment used for card (create one named Card if needed)

Cashier on a POS Invoice: Pay → Card.
Standard Point of Sale: submit a card tender; the page waits on the terminal, then submits only after APPROVED.

3. Gateway API

Authorization: Bearer

POST /v1/payments

{
  "pos_invoice": "POS-INV-00045",
  "amount": 25.00,
  "terminal_id": "CTPTST01",
  "idempotency_key": "POS-INV-00045:25.00"
}

GET /v1/payments/
GET /v1/invoices/POS-INV-00045/payment
GET /health (no auth)

Tests

cd gateway
pip install -r requirements-dev.txt
pytest -q

Related Accounting apps for Frappe & ERPNext

  • Books — Free Accounting Software
  • Lending — Open Source Lending software
  • Payments — A payments app for frappe
  • Banking — Load your bank transactions into ERPNext and reconcile them with your vouchers.
  • Erpnext Quota — App to manage ERPNext Site, User, Company and Space limitations
  • Utility Billing — The Utility Billing & Property Management App is a powerful addition to ERPNext, designed to streamline utility billing, property leasing, and tenant management. Ideal for municipal utilities, real estate managers, and property developers.
  • Expense Request — ERPNext Expense Requests
  • Vendor Payments — A frappe app that has workflows and reports to make payments to vendors by a company and track them