Repository navigation
Releases: P2Flux/sdk-php
Releases · P2Flux/sdk-php
Release list
v0.14.0
Added
- Private payments with Hinkal (live on the P2Flux API since 26 October 2026).
'private_payment' => 'hinkal'oncreatePayment()andcreatePaymentLink()(onceandreusable, not subscriptions) adds "Pay
privately with Hinkal" to the hosted checkout; the answer,resolvePayment()and link terms carry
private_payment. A verification'saccounting.refundableisfalsefor a payment made through a
privacy service (refund it by hand); link payments in the manage view carryrefundableand
screening. Requests and answers were already passed through unchanged, so 0.13.0 code can use it
too; this release documents it. (https://p2flux.com/docs/payments.html#private)
0.13.0 - Redirect checkout
Added
- Redirect checkout.
return_urloncreatePayment()andcreatePaymentLink(): after paying, the
hosted checkout sends the buyer back withp2flux_reference,p2flux_txandp2flux_statusin
the query. Every create answer now carriescheckout_url, the hosted page to send the buyer to.
resolvePayment()and link terms reportreturn_url. An older API leaves both out. Answers were
already passed through unchanged, so 0.12.0 code sees the new fields too; this release documents
them. (https://p2flux.com/docs/payments.html#return)
0.12.0 - Optional webhooks
Added
- Optional webhooks (live on the P2Flux API since 15 October 2026). Add
notify_url(a public
https URL) tocreatePayment()orcreatePaymentLink()and P2Flux POSTspayment.paid,
subscription.chargedorsubscription.updatedthere, retrying for about 18 hours. Without it
nothing changes. The response repeatsnotify_urlonly when the payment or link is watched.
(https://p2flux.com/docs/webhooks.html) handleNotification($body, $expect)- confirms a notification with the API before you fulfil:
['reference' => ...]for a payment,['link_id' => ..., 'manage' => ...]for a link. Returns
confirmed, adedupe_keybuilt from the verified payment (never the event id), and throws
P2FluxExceptionwhen the answer is not final yet (answer 5xx; it is sent again).
v0.11.1 - paywall refusal handling
Fixed
- Paywall helper: a refusal from P2Flux (a 429 rate limit above all) is answered with a 402 again -
never served free throughonUnavailable'free', and never turned into a 503 for every agent
because somebody flooded junk payment headers. Only an unreachable or failing P2Flux
(NETWORK_ERROR,INTERNAL_ERROR,RPC_ERROR,RELAYER_NOT_READY,RPC_BUSY) is "unavailable".
v0.11.0 - sanctions screening
Added
- Sanctions screening (live since 7 October 2026): error codes
PAYER_SANCTIONED(action
STOP_SUBSCRIPTION- stop charging that subscription) andRECIPIENT_SANCTIONED(action
INVALID_REQUEST- the receiving wallet is on the OFAC list; retrying gives the same answer).
Nothing was submitted when either is returned. Show buyers a neutral message such as "This wallet
cannot be used with P2Flux. No transaction was submitted." (https://p2flux.com/docs/errors.html#sanctions) verifyPayment()passes throughscreening: 'clear' | 'sanctioned' | 'unknown'(documented in the
return shape).
v0.10.0 - payment links
Added
- Payment links -
createPaymentLink(),paymentLinkStatus(),collectPaymentLink(),
stopPaymentLink()and, for custom checkouts,openPaymentLink()andsubscribePaymentLink(). Invoices paid once, fixed
prices paid many times, and subscriptions P2Flux collects for you - no server needed.
(https://p2flux.com/docs/payment-links.html) checkoutLink('link' | 'links', $token)for the buyer's link and the merchant's overview.- Error codes
INVALID_LINK,LINK_EXPIRED,LINK_UNAVAILABLE,ALREADY_SUBSCRIBED.
v0.9.0
Added
checkoutLink($page, $token)— the address that opens a checkout page (pay,subscribe,
cancel,refund,approve) for a token the API issued, with the token in the fragment.checkoutUrloption — where buyers open the checkout. Defaults to P2Flux's hosted checkout for
the API in use; set it when you host the checkout yourself
(https://p2flux.com/docs/self-hosted-checkout.html). Must be https (http only for localhost).
Nothing else changed.
v0.8.0
Added
- x402 paywall — charge AI agents for a page or an API route without an x402 library:
P2Flux\Paywall(guard($paymentHeader, $url, $userAgent)), and the two calls under it,
P2FluxClient::paywallChallenge()andpaywallRedeem(). Pay-per-request and prepaid balance; the
payment is settled before anything is served and serves one response.examples/paywall.php. - Usage pricing —
Paywall::usage($paymentHeader, $url, $maxPrice, $work)and
P2FluxClient::paywallVerify(): the agent signs for at most$maxPrice(x402upto), you charge
what the request cost (paywallRedeem(..., $amount)). - Requests signed as bots (Web Bot Auth) count as agents under
agentsOnly(guard(..., ['signed' => true]));
an agent's prepaid refund request is answered with its receipt.
Nothing else changed.
v0.7.3
Documentation, examples and PHPDoc. No behaviour changed: every method keeps its name, arguments
and return shape, and no API or payment path was touched.
Added
docs/payment-flow.md— the whole merchant lifecycle in one page, including the browser half
the SDK never sees: the checkout handshake, whyp2flux.payment.completedis a claim, and how to
make the paid transition happen exactly once.docs/recovery.md—recoverPayment(),recoverCharge()and a table of what to do after an
ambiguous request, per operation. Both other pages now link here instead of repeating it.docs/frameworks/laravel.mdanddocs/frameworks/symfony.md— the SDK used through the
container: binding, constructor injection, a create action, a repeat-safe verify action, a renewal
command and exception mapping. No Laravel package and no Symfony bundle: neither is needed.docs/testing.md— how to test an integration without spending anything: the transport
contract, a fake transport, a canned response per outcome worth a test, and the Laravel and
Symfony overrides. The SDK still ships no dev dependencies.docs/production-checklist.md— short, and every line is something that has gone wrong.- A recipes section in
docs/errors.md— API unreachable, validation,RATE_LIMITED,
CONCURRENCY_LIMIT, sponsorship unavailable, gas quotes, "it already happened", and who acts. - A glossary in
docs/getting-started.md— intent, reference, capability, salt, base units. examples/complete-payment-flow/— a runnable merchant integration: order, checkout
handshake, repeat-safe verification, recovery fallback. It runs against the canned API, so no
wallet, USDC or chain is involved.tests/complete-flow.phpdrives it end to end incomposer test.- More, smaller examples, one operation each:
create-sponsored-payment.php,
recover-payment.php,subscription-signup.php,charge-subscription.php,recover-charge.php.
subscription.phpis gone;network-fee-in-usdc.phpnow explains the accounting block.
Changed
- PHPDoc array shapes on every response a caller reads —
createPayment(),verifyPayment(),
recoverPayment(),recoverCharge(),capabilities(),status(),prepareRefund()and the
rest — so PhpStorm and PHPStan can see the keys. The shapes are unsealed (...), so a new API
field never breaks a static analyser. Two methods carried a second docblock that hid the first
from every IDE; those are merged. No signature changed. - The README leads with the first successful integration: install, a five-minute payment, the
checkout flow, verify before fulfilling, USDC network fees, subscriptions, then links. tests/stub-api.phpanswersPAYMENT_CONFIRMINGfor a hash starting0xc0and
TRANSACTION_NOT_FOUNDfor one starting0xbad, so the waiting and rejection paths are reachable
offline.tests/docs.phpchecks documentation recursively, derives the current version from
package.jsonrather than a hard-coded list, and fails on claims this product does not support.
Install
composer require p2flux/sdk-phpv0.7.2
Packaging and documentation only. No behaviour changed: every method keeps its name, arguments
and return shape, and no API or payment path was touched.
Changed
- The Composer package is
p2flux/sdk-phpand is published on Packagist, so installation is
composer require p2flux/sdk-php— norepositoriesblock and no VCS pin. The namespace,
P2Flux\, and the PSR-4 layout are unchanged; the old name was never published anywhere. composer.jsoncarries production metadata (keywords, homepage, issue/source/docs links) and
composer test, which runs the whole offline suite.- The README is a standalone entry point: install, requirements, a five-minute quickstart,
configuration, the USDC-network-fee flow, error handling and links to everything else. - The integration guide was split into one page per topic —
docs/getting-started.md,
docs/payments.md,docs/network-fee-in-usdc.md,docs/subscriptions.md,docs/refunds.mdand
docs/errors.md.docs/guide.mdis now the index. - Every example loads
vendor/autoload.phpand reads its configuration from the environment, and
fails with the missing variable's name rather than a stack trace.examples/one-time.phpis now
examples/create-payment.php.
Added
examples/verify-payment.php— server-side verification and therecoverPayment()fallback.
P2Flux sends no webhooks; this is the trust boundary, and the documentation now says so plainly.tests/examples.phpruns every example againsttests/stub-api.php, a canned API on loopback,
andtests/docs.phpchecks that every documented class, method, option and snippet still exists
and parses. Both are offline and part ofcomposer test..gitattributeskeeps the Composer dist archive to the library itself.
Install
composer require p2flux/sdk-php