Skip to content

Wave 2: finish receiver -> customer rename, drop Receivers/ApiKeys, add wire-contract check - #34

Merged
ericviana merged 3 commits into
mainfrom
eric/customers-wave-2
Aug 3, 2026
Merged

ericviana merged 3 commits into
mainfrom
eric/customers-wave-2

Conversation

@ericviana

Copy link
Copy Markdown
Member

Held: do not merge yet

This PR targets the API spec that blindpay-v2 #1799 will make live in production, not
what is deployed today. Merging before that deploy ships breaking changes against the
current wire contract. The orchestrator merges this once a production probe confirms
the #1799 cutover.

What breaks

  • Every remaining receiver_* field this SDK modeled is renamed to customer_*:
    • receiver_local_amount -> customer_local_amount (quotes, payouts)
    • receiver_wallet_address -> customer_wallet_address (transfers, transfer quotes)
    • receiver_network -> customer_network (transfers, transfer quotes)
    • receiver_token -> customer_token (transfers, transfer quotes)
    • receiver_invite_redirect_url -> customer_invite_redirect_url (instance settings)
    • receiver_id -> customer_id on Payin, Payout/PayoutOnEvmOut,
      Transfer/TransferOut, and the terms-of-service initiate input
    • Owner.customerId now only reads customer_id; the receiver_id fallback is
      dropped (the target spec's CustomerOut.owners[] schema does not mark either key
      required, so the property stays nullable)
    • ListPayinsInput/ListPayoutsInput drop the transitional receiverId filter
      (the target list endpoints only accept customer_id)
  • receiver.new / receiver.update / receiver.delete webhook events are removed
    from WebhookEvents (they stop firing at cutover; wave 1 already marked them
    deprecated). The SDK was also missing several event cases the spec has always had
    (limitIncrease.new, limitIncrease.update, transfer.new, transfer.complete,
    transfer.update, virtualAccount.new, virtualAccount.complete,
    wallet.inbound, wallet.new) plus a pre-existing typo (tos.accepted should be
    tos.accept) — all added/fixed here since the new contract check treats a spec
    webhook topic missing from WebhookEvents as a hard failure.
  • The deprecated Receivers resource/wrapper and ReceiverStatus type are removed
    ($blindpay->receivers no longer exists; use $blindpay->customers).
  • The ApiKeys resource is removed ($blindpay->instances->apiKeys no longer
    exists). Product decision: API Keys is deliberately absent from the public
    reference, so it doesn't belong in the SDK regardless of what the spec still lists.
  • VERSION bumps to 3.0.0 (major).

Intentionally unchanged

  • receiver_amount (singular) keeps its name everywhere — it's the receiving-side
    amount on quotes, payins, payouts and transfers, and the changelog explicitly
    exempts it.
  • CurrencyType keeps its sender/receiver enum values.
  • Stored re_-prefixed IDs are never rewritten; only the field/parameter names that
    carry them changed. Verified in the diff and in the test fixtures.
  • The otc_only_supported_for_sender_without_cover_fees_and_receiver_with_cover_fees
    slug isn't modeled by this SDK, so there was nothing to touch.

Versioning

Go isn't part of this repo (this is blindpay-php), so only this package's version
moved: 3.0.0 (major/breaking), per the repo's SemVer table (rename/removal of
fields, methods, and resources = MAJOR). No tag or release is created by this PR.

New: wire-contract check (CI-gated)

Every field-name bug this rename wave had to fix was the kind a mechanical check
would have caught, so this PR adds one:

  • .api-sync/spec-snapshot.json: the target spec committed into the repo so the
    check is hermetic (kept current via sync PRs going forward).
  • scripts/contract-check.php: a dependency-free script (php scripts/contract-check.php,
    also composer run contract-check) that tokenizes every fromArray()/toArray()
    in src/Resources and src/Types and:
    • Hard fails if a declared wire key ($data['x'] read, 'x' => ... write) does
      not exist as a property name anywhere in the snapshot, unless allow-listed.
    • Hard fails if any spec webhook topic has no matching WebhookEvents case
      (checked explicitly against the enum).
    • Warns (does not fail) on spec properties the SDK never reads or writes.
  • .api-sync/contract-allowlist.json: seeded only with genuine pre-existing
    divergences unrelated to this rename that I found while building the check and did
    not fix here — a legacy BankAccountResponse shape (account_holder_name,
    swift_code, is_primary), a stray aiprise_validation_key that isn't a real
    response property anywhere, a dropped individual_holding_doc_front_file, a
    Payin.billing_fee vs billing_fee_amount duplicate, and a tracking_partner_fee
    shape that doesn't exist on any of Payin/Payout/Transfer's wire responses.
    Nothing wave 2 should fix is in this list.
  • Wired into .github/workflows/main.yaml as a new contract-check job alongside
    lint/tests.

Verified the check actually catches this week's bug class: reverting one rename
locally (Payin.customerId back to reading receiver_id) makes it fail with
Payin.receiver_id (read) -- not found anywhere in the spec snapshot and not allow-listed; restoring the fix makes it pass again.

https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs

@ericviana ericviana added the hold-until-1799-deploy Breaking change; hold merge until blindpay-v2 #1799 is deployed to production label Jul 27, 2026
@BernardoSM

BernardoSM commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

…re contract check

Wave-2 breaking release (3.0.0): the remaining receiver_* field renames, removal of
the receiver.* webhook events and legacy surface, and a mechanical contract-check in CI
that validates every SDK-declared wire key and the webhook enum against the committed
public spec snapshot (.api-sync/spec-snapshot.json).

Held until blindpay-v2 #1799 reaches production; the branch history was rebuilt as this
single commit so the snapshot only ever contains the public filtered spec.

Claude-Session: https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs
@ericviana
ericviana force-pushed the eric/customers-wave-2 branch from 7651205 to 0043a7e Compare July 27, 2026 22:45
@ericviana
ericviana merged commit 8a8404c into main Aug 3, 2026
5 checks passed
@ericviana
ericviana deleted the eric/customers-wave-2 branch August 3, 2026 19:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hold-until-1799-deploy Breaking change; hold merge until blindpay-v2 #1799 is deployed to production

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants