Skip to content

fix: correct type divergences (pagination, billing fee, enums, wallet creation, payin tracking) - #37

Merged
ericviana merged 1 commit into
mainfrom
eric/fix-type-divergences
Aug 4, 2026
Merged

ericviana merged 1 commit into
mainfrom
eric/fix-type-divergences

Conversation

@ericviana

Copy link
Copy Markdown
Member

Summary

Fixes six live defects recorded in .api-sync/known-divergences.json and .api-sync/unmodeled.json, verified against the current published OpenAPI spec:

  • PaginationMetadata: next_page/prev_page are nullable string cursors in the spec; the SDK declared them as int. Any real paginated response with a next/prev page threw a TypeError. Fixed to ?string.
  • Payin.billingFeeAmount: spec declares number|null; the SDK declared ?string with no cast. Threw whenever the fee was populated (end of month). Fixed to ?float with a cast in fromArray.
  • BankAccountType::SAVINGS: wire value is saving (singular); the SDK case value was savings (plural). A real saving account_type response failed to parse via ::from(). Fixed the case value.
  • EstimatedAnnualRevenue: top bucket had an extra digit (2500000000_plus instead of 250000000_plus). Fixed the case value.
  • CreateCustodialWalletInput: name is required by the spec (required: ["network","name"]) but was missing from the constructor entirely, so every custodial wallet creation call was rejected by the API. Added $name as a required promoted constructor param (positional shift, endpoint was unusable before this).
  • Payin/payout tracking_payment: both shared a single TrackingPayment decoder, but the spec shapes differ. Payin's tracking_payment lacks the payout-only fields (provider_transaction_id/provider_status/estimated_time_of_arrival) that class declared as non-nullable strings, so decoding a payin's tracking data threw a TypeError. Split into PayinTrackingPayment (step/provider_name/completed_at) and PayoutTrackingPayment (adds the four payout-only fields, all nullable per spec).

Bumps VERSION (BlindPay::VERSION constant) to 3.2.0. Removes the ledger entries these fixes resolve from known-divergences.json and unmodeled.json, and updates the corresponding spec-map.json notes.

api-sync --audit-types delta

12 mismatches resolved, 0 introduced:

- PaginationMetadata.next_page: spec=string|null sdk=int mismatch=category+nullability [recorded]
- PaginationMetadata.prev_page: spec=string|null sdk=int mismatch=category+nullability [recorded]
- PayinOut.billing_fee_amount: spec=number|null sdk=?string mismatch=category [recorded]
- PayinOut.tracking_payment.provider_name: spec=string|null sdk=string mismatch=nullability [NOT YET RECORDED]
- PayoutOnEvmOut.tracking_payment.{estimated_time_of_arrival,provider_name,provider_status,provider_transaction_id}: nullability [NOT YET RECORDED]
- PayoutOut.tracking_payment.{estimated_time_of_arrival,provider_name,provider_status,provider_transaction_id}: nullability [NOT YET RECORDED]

php scripts/api-sync.php --check passes clean before and after. composer test (118 tests, 729 assertions), composer run lint:check, and php scripts/contract-check.php all pass.

Test plan

  • composer install + composer run test -- 118 passed
  • composer run lint:check -- clean
  • php scripts/api-sync.php --check -- exit 0
  • php scripts/api-sync.php --audit-types before/after diff captured above
  • php scripts/contract-check.php -- OK

https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs

…ling fee, enums, wallet creation, payin tracking)

Fixes six live defects surfaced by the api-sync patcher's ledgers, verified against the
current published OpenAPI spec:

- PaginationMetadata.next_page/prev_page are nullable string cursors, not int; the SDK
  threw a TypeError on any real paginated response with a next/prev page.
- Payin.billingFeeAmount is a number in the spec; the SDK declared it as string with no
  cast, throwing whenever the fee was populated.
- BankAccountType::SAVINGS carried the wrong wire value ('savings' instead of 'saving'),
  so a real savings account_type response failed to parse.
- EstimatedAnnualRevenue's top bucket had an extra digit ('2500000000_plus' instead of
  '250000000_plus').
- CreateCustodialWalletInput was missing the required `name` field, so every custodial
  wallet creation call was rejected by the API.
- Payin and payout shared a single TrackingPayment decoder, but the payin tracking_payment
  shape lacks the payout-only fields (provider_transaction_id/provider_status/
  estimated_time_of_arrival) that class required as non-nullable strings, throwing a
  TypeError on payin fetch. Split into PayinTrackingPayment and PayoutTrackingPayment
  matching each spec shape.

Bumps VERSION to 3.2.0. Removes the known-divergences/unmodeled ledger entries these
fixes resolve.

Claude-Session: https://claude.ai/code/session_01F1stiNzuNtJXoXtiW9ZCbs
@BernardoSM

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.

@ericviana
ericviana merged commit c1e21fa into main Aug 4, 2026
6 checks passed
@ericviana
ericviana deleted the eric/fix-type-divergences branch August 4, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants