Use case

SaaS payment compliance: KYB, AML awareness, and the records an audit asks for

Most SaaS companies meet payment compliance through someone else's checklist: a SOC 2 auditor mapping the billing system, a banking partner asking how money moves, a finance review tracing revenue. "We take crypto" is the start of that conversation, not the end of it. The concrete questions are: who is the legal entity behind this account and was it verified, are the payments running through it screened, and can you tie every subscription charge and every developer payout back to an account and a cycle? This page covers how halfin's payment rail supports those answers — KYB at onboarding, AML awareness on the rail, and an invoice-to-hash and payout-to-hash trail finance can reconcile — and where the boundary stops. Your software business still owns customer identity, account decisions, data-protection obligations, and whatever your product is regulated for in its own markets. None of this is legal advice.

01

What 'compliance' means for a SaaS business taking crypto

Payment compliance gets talked about as one obligation, but on a billing flow it breaks into a short list of answerable questions. Who is the legal entity collecting subscription revenue and authorizing payouts, and was it verified? Are the payments moving through that account screened, with a record of it? Can you tie a confirmed subscription charge back to a specific account and cycle, and a payout back to a specific payee and period — and show the same account was not double-billed nor the same partner double-paid? Those are exactly the questions a SOC 2 control narrative, a finance audit, or a banking partner asks, and a defensible process answers each with evidence instead of recollection.

halfin sits on the payment side of those questions. It does not decide which customers may sign up, which plans an account qualifies for, or what your product is permitted to do in a given country — those judgments live in your sign-up, entitlement, and account systems. What halfin provides is a rail that supports KYB at onboarding, applies AML awareness to the movement of funds, and leaves a concrete trail behind every invoice and every payout. Your product supplies the customer and account decisions; halfin supplies the payment execution and the evidence.

One point worth stating plainly: halfin is infrastructure, not a license and not a certification. Your business may be licensed, registered, or certified for something in its own jurisdiction, and that status belongs entirely to you — halfin does not hold, grant, or stand in for it. Treat the items below as process to run with your own counsel, not a credential you inherit by integrating. Nothing here is legal advice.

02

KYB at onboarding, before the first invoice

Compliance starts before the first subscription charge lands. When a software business becomes a halfin merchant it goes through KYB onboarding — know-your-business verification of the legal entity that will collect deposits and authorize payouts. That establishes who the account holder is on the halfin side and is a prerequisite for moving real funds. It is deliberately a one-time, account-level gate, separate from any per-customer checks your product runs at sign-up.

Keep the two layers distinct, because conflating them is where SaaS teams get into trouble. KYB verifies the merchant — your company as a legal entity. It does not verify your customers, and halfin makes no claim about them. Customer identity, the decision about who may open an account, and any plan-eligibility, residency, or export-control checks remain your responsibility and stay in your systems.

This split matters more in self-serve SaaS than almost anywhere else. An API-first product creates invoices programmatically, with no human reviewing each new account at the moment of charge — so the checks that would catch a customer who should not be there have to live in your onboarding logic, not the payment call. Treat KYB as a fact about the merchant and the per-account decision as a fact about your product; never present one as the other.

  • KYB at onboarding establishes the software business as a merchant — a one-time, account-level gate.
  • Customer identity, plan eligibility, and export-control checks stay in your sign-up and entitlement systems.
  • KYB verifies the business; it is not a product certification and cannot be presented as one.
  • In self-serve flows there is no human per charge — the account checks belong in your onboarding logic, not the invoice call.
03

AML awareness on subscriptions in and payouts out

AML awareness is a process the rail applies to the movement of funds, not a certificate you can hang on the wall. Inbound, a subscription payment arrives as a confirmed on-chain deposit against an invoice; the counterparty and the deposit are screened as part of how halfin processes payments, and the result is recorded against the invoice. Outbound, payouts to plugin authors, API resellers, revenue-share partners, and affiliates are screened before release. None of this replaces the screening you own on your own side — it complements it.

The control point that matters for you is the pending-approval step on payouts. A payout you submit through the API does not move funds the instant it is called — it enters a pending-approval state and is released from the dashboard. So the staging path (your back office submitting the run) and the release path (a human or policy approving it) are separate by design. Run your own counterparty and wallet screening between those two steps, and release only the lines that clear. A line that fails screening is simply not released, with a dashboard record of that decision.

Address validation is a baseline halfin handles on its own: a destination is checked for the chosen network before a payout is accepted, so a malformed address or a wallet that cannot receive the selected asset is rejected up front rather than burning a send. That is a correctness check, not a sanctions check. Validation stops you paying into a broken address; your own screening stops you paying a counterparty you should not pay.

04

Data, residency, and tax: the questions halfin does not answer

A SaaS product selling the same software into a hundred countries inherits a different obligation in each one, and most are not about payment. What customer data you may store and where, whether your product needs an export license for a given destination, how subscription revenue is taxed and where VAT or sales tax is owed — these are data-protection, trade, and tax questions that sit squarely on your side. A crypto payment rail does not make any of them disappear, and it is a mistake to read "halfin handles cross-border payments" as "halfin handles cross-border compliance."

Name the tempting wrong assumption directly: that settling in crypto moves a customer outside your data and tax obligations. It does not. The customer relationship, the account, and the personal data you hold are yours regardless of how they pay, and a charge settling in USDT instead of on a card changes nothing about which privacy law or tax authority applies. The asset is a settlement detail; the obligation follows the customer and the product.

What the rail does change is the evidence you can produce. Because collection, payouts, conversion, and refunds all run through the same API and dashboard, you have one consistent record of where money came from and where it went — independent of how many countries your customers and partners sit in. Each invoice is anchored to a fiat amount you billed, so your reporting and tax basis stay in your home currency even though customers settle in crypto. The travel rule is a useful example of a concept to understand as process, not status: an operating idea about how information accompanies certain transfers, never a certification halfin holds on your behalf.

05

Who owns what: the compliance boundary

The cleanest way to keep a SaaS payment integration maintainable is to draw the boundary explicitly and keep each side's system of record on its own side. Your product owns who the customer is, whether they may use the service, and the data, tax, and trade obligations of selling where it sells. halfin owns whether a payment confirmed, where it came from, where a payout went, and the records of all of it. The two reconcile through signed events, and neither does the other's job. The table below is that boundary in concrete terms — the same split a finance team should recite when a SOC 2 auditor or a banking partner asks who is responsible for what.

ResponsibilityOwned by your SaaS businessOwned by halfin (the rail)
Customer identity and account eligibilityYes — sign-up, KYC where applicable, plan checksNo
Product licensing / export controlsYes — in its jurisdictions, with counselNo
Merchant entity verification (KYB)Provides documentsPerforms KYB at onboarding
Counterparty / wallet screeningOwns the decision and the watchlistsAML awareness on the rail; address validation
Subscription billing recordReconciles against its plan catalogInvoice + confirmation + signed webhook
Developer / affiliate payout recordApproves the runPayout + idempotency key + transaction hash
Customer data protection and privacyYes — its own DPAs and policiesNo
VAT / sales tax and revenue reportingYes — with its own counselFiat-anchored amount per invoice
06

The audit trail an integration leaves behind

The practical payoff of the boundary above is that every payment leaves an artifact you can point to. A subscription charge resolves to a fiat-anchored invoice, a confirmation under the chain's threshold with reorg-aware crediting, and an HMAC-signed webhook your backend verified before acting. A developer or affiliate payout resolves to an idempotency key, a dashboard approval record, and an on-chain transaction hash. None of that is recollection — it is data finance can export and show to a SOC 2 auditor or a banking partner.

Idempotency is the load-bearing property on both sides. Each payout line carries its own idempotency_key, so a partner run retried after a network timeout settles once, not twice — which is also a compliance point, because "we never double-paid a developer" becomes an answerable question rather than a hopeful one. The same property protects inbound billing: an idempotency key scoped to the cycle means a retried billing job returns the existing invoice instead of charging an account twice for the same period. The minimal shape of an approved payout line below shows where that key lives; the full request and response schemas are defined at docs.thehalfin.com.

Pair that with the signed webhook on the inbound side and you have both halves of the trail. Verify the HMAC signature on every event before acting on it, then attach the confirmed invoice or completed payout to the account, cycle, or partner in your own records — which is what turns a pile of on-chain transactions into a reconciliation your finance team and auditor can both follow.

# One line of an approved payout run — fan-out over POST /api/v1/payouts,
# one idempotency_key per line so a retried run settles once, not twice.
curl -X POST https://api.thehalfin.com/api/v1/payouts \
  -H "X-API-Key: $HALFIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "USDC",
    "amount": "1200.00",
    "destination": "0x9f...pluginAuthorWallet",
    "idempotency_key": "00000000-0000-4000-8000-000000000042"
  }'

# Submitting enters pending-approval; release happens in the dashboard after
# you screen the destination. The completed payout resolves to a transaction
# hash and a payout.completed webhook — verify its HMAC first.
# Full schemas: docs.thehalfin.com.