The defining shape of a Perpay integration is the paycheck split. Each direct deposit Perpay receives on payday is the parent event, and the Marketplace pay-down, the card pay-down, the $3 Perpay+ subscription line and any one-off debit-card top-up all hang off it as typed children. The money never sits in a checking account waiting to be pulled — it is allocated off the wages at the payroll provider before the rest reaches the user's main account. A working integration mirrors that tree rather than flattening it into a stream.
The brief below names what we would pull, the authorized route we would take to reach it, the way we deliver the work, and the engineering specifics that come up on a Perpay build in particular. The page does not litigate whether Perpay publishes a developer console — that is not the route we use and not what we sell.
Where Perpay holds the data we'd pull
Perpay's own help center describes the Account Activity view as the authoritative record of how each direct deposit splits across the two products. The table below matches that structure, plus the customer-profile and card-account state that a full integration also needs.
| Data domain | Where it originates in the app | Granularity | What an integrator does with it |
|---|---|---|---|
| Direct Deposit events | Dashboard → Direct Deposit tab → Account Activity, recorded as a positive deposit on the user's actual payday per Perpay's help docs | Per paycheck, dated, with the deposit amount | Parent event for reconciliation; the timestamp that all child splits hang off |
| Marketplace Payment | Same Account Activity ledger, allocated to the Marketplace balance | Per deposit, per order line | Pay-down schedule for each open Marketplace order, useful for PFM and for forecasting shipment release on early orders |
| Card Payment | Account Activity ledger, allocated to the Perpay Credit Card balance | Per deposit | Posting record against the Celtic Bank card; lets a PFM tool reconcile statement balance independently of the card processor |
| Perpay+ Payment | First payment of the month on enrolled accounts, allocated to the Perpay+ subscription (described on the help center as $3.00 per month) | Monthly, per enrolled account | Flags Perpay+ status and lets a credit-coaching surface explain the $3 line |
| Card Deposit (top-up) | Extra payment on the Marketplace balance made via debit or credit card; shows as a positive Card Deposit per the help docs | Per off-cycle top-up | Out-of-band payments — important so a sync run does not treat them as missing direct deposits |
| Marketplace order book | Shop / order history | Per order, with status, remaining balance, ship-on-first-payment flag | Order-level state for fulfillment dashboards and for income-share modeling |
| Spending limit and utilization | Account dashboard; new-customer ranges are described on third-party reviews as roughly $500 to $1,000, growing with on-time history | Current limit, used amount | Headline number that Perpay+ reports to the bureaus |
| Perpay+ status and reported snapshot | Perpay+ section; reporting to Experian, Equifax and TransUnion per the help center; report cadence stated as the second half of each month, with the limit reported within 30–60 days of activation | Enrolled / not, last reported limit, last reported on-time payment history | Lets a credit-coaching app explain bureau updates instead of waiting for the user to notice |
| Celtic Bank Mastercard account state | In-app card screens; statement copy itself is mailed on request via the number on the card or supplied by Customer Success, per Perpay's docs | Balance, recent transactions visible to the cardholder, rewards accrual (2% per the rewards agreement), monthly servicing fee ($9 per the cardholder agreement) | Card-side reconciliation; statement-PDF retrieval is documented as a manual fallback because it is not in self-service |
| Customer profile | Onboarding and profile screens | Verified income basis, employment, employer payroll provider, Perpay-assigned routing/account number used for the deposit | Identity-side fields for KYC re-use; the routing/account number is versioned (it can change), and the integration carries the history |
The route we'd take to reach it
Three routes are realistic for Perpay. We name what each one reaches and which one we would actually push on, given the shape of this account.
Authorized interface integration on a consenting account
The customer logs in to their own Perpay account; we drive the same screens they would, on their behalf, against the live app and web surfaces. Every Account Activity field is reachable this way, the Marketplace order book is reachable, and the card-side data the user can see in-app is reachable. Effort is moderate — the auth chain is the work, not the parsing. Durability is good as long as the integration is built to fail loud on layout changes rather than silently degrade; the maintenance lane is small checks when Perpay ships an app or portal update. This is the route we would push on for a Perpay build.
User-consented credential access via a delegated session
A close cousin of the above, used when the partner is fronting an experience (a credit-coaching app, a personal-finance dashboard) and wants the user to grant access once and walk away. Same data surface; the difference is the consent record, the credential storage posture, and the refresh strategy. We handle the consent capture, the secret storage, and the silent-refresh logic on top of the same interface contract.
Native export as a fallback for the card statement
One pocket of Perpay's data is not in self-service: the formal Mastercard statement. Perpay's own help text says a paper statement is mailed on request and a fuller copy is supplied by Customer Success on request. For card-statement archives we document a hybrid: the integration carries the per-transaction stream that the user can see in-app, and the statement PDF is fetched on the rare occasion a customer needs it, through the supported request path. Stating that openly is more useful than pretending the statement is part of the live stream.
Consent posture for a US payroll-driven BNPL
Perpay's data sits across two regulatory shapes, and neither is cleanly inside a settled US data-rights regime. The Marketplace ledger is a BNPL pay-over-time product, not the deposit account or general-purpose credit card that §1033's published text was clearly drawn around; the Celtic Bank Mastercard balance is closer to a §1033 candidate but is itself unclearly placed today. The CFPB rule that would have given a partner the rights-based path into either is, as of this writing, enjoined from enforcement and back in the Bureau's hands for reconsideration — so it is not the basis we ride into the account on, and we do not present it as one.
The basis we actually rely on is the Perpay user's own authorization to act for them on their account, captured as a consent record with documented scope, expiry and a one-tap revocation. That is what makes the build defensible today. Logs of every accessed surface, data minimization (we do not pull what we are not asked to pull), and NDAs where the partner needs them are how the studio runs the engagement.
What lands in your repo at delivery
- An OpenAPI 3.1 spec for the Perpay surface as we expose it — paths for ledger pulls, order book, card account, Perpay+ status; schemas for the Account Activity event tree (parent deposit + typed children).
- Runnable source in Python (httpx + pydantic) or Node.js (fetch + zod), pick one, covering: login and session refresh, Account Activity pull with delta windows, Marketplace order list, card-side reads, Perpay+ status read.
- An auth-flow and protocol report: how login, MFA where present, token or cookie chain, and silent refresh behave on Perpay specifically — written for the engineer who will own the integration after we hand it off.
- Automated tests: contract tests against fixtures captured during the build, plus a small live smoke suite that hits a consenting account behind a kill switch.
- Interface documentation: how the Account Activity tree maps to a normalized ledger schema, how the routing/account-number versioning works, how the statement-request fallback fits in.
- Compliance and data-retention guidance written for this engagement — what we capture in the consent record, what we log, what we do not store.
Auth and the Account Activity pull
Illustrative — the field names and headers are firmed up during the build against the live surface, not invented here.
# Authorized session against a consenting Perpay account.
# Auth is whatever the live login chain is on the day of the build
# (credential post + MFA challenge where present, session cookie out).
session = perpay.login(
username = cfg.user,
password = cfg.secret,
on_mfa = prompt_user, # interactive in the dashboard,
# cached + refreshed silently in sync runs
)
# Pull Account Activity since the last successful sync.
# Perpay's own UI presents this as Direct Deposit tab -> Account Activity,
# with "View More" paging back through prior payments; we mirror that paging.
events = session.account_activity(
since = state.last_synced_at, # ISO 8601
page_size = 50,
)
# Normalize the deposit tree: one parent Direct Deposit event,
# zero-or-more typed children all keyed to the same deposit_id.
for ev in events:
if ev.type == "direct_deposit":
deposit_id = emit_parent(ev) # paycheck arrived on payday
elif ev.type in ("marketplace_payment",
"card_payment",
"perpay_plus_payment",
"card_deposit"):
emit_child(parent = deposit_id, ev = ev) # split, typed
else:
log.warn("unrecognized activity type", raw=ev.raw)
# fail loud rather than silently bucket into a default
# Card side (Celtic Bank Mastercard): balance + visible transactions.
# Formal statement PDF is not in self-service; the fallback path is
# Customer Success per Perpay's own help docs.
card = session.card_account()
emit_card_snapshot(
balance = card.balance,
transactions = card.recent_transactions,
rewards_accrual= card.rewards_balance, # 2% per Rewards Agreement
)
# Perpay+ status: enrollment, last reported limit, expected next report window.
plus = session.perpay_plus_status()
emit_perpay_plus(
enrolled = plus.enrolled,
last_reported_limit = plus.last_reported_limit,
next_report_window = plus.next_report_window, # "second half of month"
)
What we plan for on the Perpay build
- The Perpay-assigned routing/account number is a versioned field. It can change after an account update, and the employer-side payroll provider is outside Perpay's control. We carry the prior values on the user profile, back-map older deposits against the version that was live at the time, and surface a divergence flag when the payroll side and the live Perpay value drift, so a sync run does not report 'missed payment' on what is really a re-routing event.
- Account Activity is a tree, not a flat list, and we model it that way. Flattening to a stream loses the reconciliation invariant ("the children sum to the parent deposit") that makes downstream PFM and accounting actually balance. The integration emits parent + typed children with a shared deposit_id and exposes that grouping in the schema.
- The card statement PDF is documented as a manual fallback, not as live data. Perpay's own help center says the formal statement is mailed on request or supplied by Customer Success — pretending it is part of the realtime feed would set wrong expectations. We expose the transactions and balance the cardholder can already see in-app, and a clean request path for the few cases that need a stamped statement.
- Perpay+ reporting cadence is predictable and we surface it. Reporting runs in the second half of each month and the spending limit lands within 30–60 days of activation per Perpay's help docs; we expose the next expected window as a field so a credit-coaching surface can explain bureau updates instead of polling blind.
- Layout changes are caught loudly. Any sync run that meets an unrecognized Account Activity type, or a missing field on a deposit child, raises rather than silently buckets into a default — the worst integration failure mode for a paycheck-driven ledger is to swallow a category, and we design that out.
Where teams put a Perpay integration to use
- PFM / budgeting apps that want a single picture of a user's Marketplace pay-down, card pay-down and Perpay+ subscription against one paycheck — without asking the user to enter each split by hand.
- Credit-coaching surfaces that explain why a user's bureau report changed this month, using Perpay+'s known second-half-of-month cadence.
- Income-share modeling and underwriting on Perpay's own customer base, where a Marketplace order paying off cleanly is itself a signal of stable payroll allocation.
- Wage-stream and earnings-linked products that need to coexist with Perpay on the same paycheck — knowing exactly what Perpay is taking off the top changes how much wage-stream room is left.
Pricing and how this engagement runs
Source-code delivery on a Perpay build starts at $300 and is invoiced only after you have the runnable code in hand and have signed it off. The deliverables in §"What lands in your repo at delivery" — OpenAPI spec, runnable source, auth report, tests, interface docs, compliance notes — are the same set in either model. The alternative is a pay-per-call hosted API: we operate the integration, you call our endpoints, and you pay only for calls actually made, with no upfront fee. Either way the build runs in roughly one to two weeks from kickoff. Access (a consenting Perpay account or a sponsor account, depending on the partner's posture) is worked out with you during onboarding — it is part of the engagement, not a hurdle before it.
To start a Perpay build or ask a specific question about the data above, send the project brief through the contact page with the app name and what you want from it.
Screens we'd be matching against
The screenshots Perpay publishes on the Play Store are the same surfaces the integration drives against. They are the visual reference; the actual contract is verified against the live app during the build.
Adjacent BNPL and credit-builder apps in the same integration shape
The neighbourhood we work in alongside Perpay — pay-over-time products that touch payroll, credit-builder products that report to bureaus, and BNPL apps a partner often wants to unify on one ledger. Each has its own data quirks; a unified integration treats them as parallel ledgers normalized into the same event model.
- Affirm — Pay in 4 and longer monthly installments; per its own communications, reports its products to Experian and TransUnion.
- Klarna — Pay in 4 plus 6-to-36-month financing; per Klarna's site, monthly financing APRs range up to 35.99%.
- Sezzle (and Sezzle Up) — Pay in 4 with an opt-in credit-building add-on that, per Sezzle, reports payments to the three major bureaus.
- Afterpay — short-cycle Pay in 4 retail BNPL with no interest on the standard plan; primarily a retail-checkout ledger.
- Zip (formerly Quadpay) — Pay in 4 with a different stance on credit checks per its own product page; reschedulable due dates.
- Uplift — travel-specific BNPL; the ledger is dominated by single-trip orders with longer plans.
- Self — credit-builder installment loan that reports to the bureaus; a pure credit-building ledger with no shopping side.
- Kikoff — credit-builder line and store, designed expressly to produce a reportable on-time history.
- Possible Finance — small short-term installment loans aimed at users without prime credit; bureau-reported on closure.
How this brief was put together
The notes above are drawn from Perpay's own help center articles on how the product and the Account Activity ledger work, Perpay's bureau-reporting article, and the CFPB pages and the August 2025 Federal Register notice on the §1033 reconsideration. Each linked source was opened during the write-up; nothing has been asserted from secondary recall.
- Perpay — How Perpay Works (help center)
- Perpay — Where can I view my Payment History (Account Activity structure)
- Perpay — Which credit bureaus do you report to
- CFPB — Personal Financial Data Rights Reconsideration
OpenBanking Studio integration desk — Perpay mapping walked through May 2026.
Questions that come up on Perpay builds
Does the Account Activity ledger separate Marketplace and credit-card payments cleanly enough to reconcile against a payroll deposit?
Yes — Perpay's own Account Activity view splits each direct deposit into typed children (Marketplace Payment, Card Payment, Perpay+ Payment, optional Card Deposit), so the reconciliation tree is already in the data we pull. We model the deposit as the parent event and emit the children as siblings keyed off the same deposit timestamp, which is how downstream PFM and accounting tools can balance against a single paycheck without guessing splits.
What happens when the routing/account number Perpay assigns for payroll rotates, or when an employer's payroll provider changes mid-engagement?
The internal Perpay routing/account number can change after an account update and the payroll provider (ADP, Paycom, Workday, Gusto, Paychex, Paycor and similar) lives outside Perpay entirely. We treat the deposit-instrument as a versioned field on the user profile, store the prior values for back-mapping older deposits, and surface a flag when the live value diverges from the one the payroll side is using so a sync run does not silently report "missed payment" on what is actually a re-routing event.
Can a single consenting Perpay session expose both the Marketplace order history and the Celtic Bank Mastercard statements, or do they sit behind separate auth?
Both products are reached through the same Perpay login, but the card statement copy itself is not in the self-service UI — Perpay states a paper statement is mailed on request via the number on the back of the card, and a fuller statement is supplied by Customer Success on request. The integration we build covers everything the consenting user can see in-app (card balance, transactions visible to the cardholder, rewards accrual, payment posting), and we document the statement-request path as a separate manual fallback so the data set we promise matches what is actually pullable.
How does Perpay+ enrollment show up in the data, and how do we know what is being sent to the credit bureaus?
Per Perpay's own help docs, Perpay+ reporting goes to Experian, Equifax and TransUnion, the first payment of each month is allocated to the $3.00 Perpay+ subscription, and the spending limit reports within 30–60 days of activation, usually in the second half of the month. We expose three fields: the enrollment state, the most recent reported limit and payment-history snapshot, and the next expected report window — so a partner can predict the bureau update instead of polling blind.
App profile (neutral recap)
Perpay - Shop and Build Credit is a US BNPL marketplace and credit-card app from Perpay, Inc. in Philadelphia. The marketplace lets a customer spend up to a limit (described by Perpay and third-party reviews as commonly $500–$1,000 for new users, growing with on-time history) on Marketplace inventory and pay it back over time through automatic deductions from their paycheck via a secondary direct-deposit account at Perpay. Perpay+ is an opt-in $3.00/month subscription that reports the Marketplace account to Experian, Equifax and TransUnion. The Perpay Mastercard, issued by Celtic Bank, is unsecured, carries a $9 monthly servicing fee and 2% rewards per the published Cardholder Agreement and Rewards Program, and pays itself down through the same paycheck-deduction channel. Identifiers stated here are sourced from Perpay's own pages or its Play Store listing rather than asserted as bare fact.