Skip to content

feat: add card transactions and automated release tagging#9

Merged
GREENFONTS merged 3 commits into
mainfrom
dev
Jun 30, 2026
Merged

feat: add card transactions and automated release tagging#9
GREENFONTS merged 3 commits into
mainfrom
dev

Conversation

@GREENFONTS

Copy link
Copy Markdown
Collaborator

Two unrelated changes bundled in this branch:

Automated releases. Added release-please (.github/workflows/release-please.yml, release-please-config.json, .release-please-manifest.json) so version numbers and release tags are decided automatically from Conventional Commits on every merge to main, instead of tagging by hand like v0.1.0 was. Future releases just need a feat:/fix: commit merged, then approving the resulting Release PR.

Card transactions. Added support for charging a card directly (raw PAN/CVV/PIN) as an alternative to hosted checkout: ChargeAsync, AuthorizeOtpAsync (OTP-required cards), and Authorize3dsAsync (PCI DSS-gated, requires separate Monnify activation). These live on IMonnifyCollectionsClient rather than a separate client, since card charging completes a transaction from InitializeTransactionAsync the same way InitiateBankTransferAsync does. As a result, the whole IMonnifyCollectionsClient now registers with automatic retry disabled (since ChargeAsync directly debits a card) - more conservative than its other methods strictly need, traded for keeping every collection method on one client.

Sandbox-tested with Monnify's documented test cards: the request format is handled correctly (the dedicated "Failed Card" number returns its own distinct error), but the no-OTP/OTP/3DS cards all returned "Card bin not found. Please contact support." instead of completing a charge - reads as a sandbox account configuration gap rather than a request-format issue. See docs/COMPATIBILITY.md for details; AuthorizeOtpAsync's real response shape and ChargeCardResult.TokenId remain unverified as a result.

Also includes a docs-only fix found while cross-referencing a Monnify doc page for InitiateBankTransferAsync: their sample shows the USSD field as ussdCode, but a real sandbox call confirmed it's ussdPayment, which the SDK already had right.

Checklist

  • Tests added/updated and passing (dotnet test)
  • dotnet format --verify-no-changes passes
  • CHANGELOG.md updated under [Unreleased]
  • docs/COMPATIBILITY.md updated for any endpoint you implemented or changed
  • No secrets, tokens, or real API keys committed

IMonnifyCardsClient covers direct card charges as an alternative to
hosted checkout: ChargeAsync, AuthorizeOtpAsync, and the PCI
DSS-gated Authorize3dsAsync. Registered with automatic retry
disabled, same reasoning as Disbursements/Bills - ChargeAsync
directly debits a card, so an ambiguous failure must be resolved via
GetTransactionAsync rather than retried.

Sandbox-tested with our documented test cards: the request shape is
handled correctly (the dedicated "Failed Card" number gets its own
distinct error), but the no-OTP/OTP/3DS cards all returned "Card bin
not found" instead of completing a charge - reads as a sandbox
account configuration gap rather than a request-format issue. See
docs/COMPATIBILITY.md for details; AuthorizeOtpAsync's response shape
and ChargeCardResult.TokenId remain unverified against a real
OTP-required response as a result.
Re-verified InitiateBankTransferAsync against a fresh sandbox call while
cross-checking a newly pasted doc sample. The existing model was already
right (ussdPayment, not the ussdCode our simplified doc sample shows) -
this only updates docs/COMPATIBILITY.md with the verified field list and
flags an unmodeled, always-null productInformation field.
Card charging completes a transaction started by InitializeTransactionAsync,
the same way InitiateBankTransferAsync does - moved ChargeAsync,
AuthorizeOtpAsync, and Authorize3dsAsync (plus their models) onto
IMonnifyCollectionsClient instead of a separate IMonnifyCardsClient,
under Collections/Models/Transactions.

The whole Collections client now registers with automatic retry
disabled, since ChargeAsync directly debits a card - more conservative
than its other (non-money-moving) methods strictly need, traded for
keeping every collection method on one client. Also corrected the
bank-transfer doc note found while cross-referencing this: the real
ussdPayment response field, not ussdCode as our simplified doc sample
shows - the SDK already had this right.
@GREENFONTS
GREENFONTS merged commit 25a62b3 into main Jun 30, 2026
3 checks passed
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.

1 participant