sol-parts / payum-privatbank-payparts
Payum gateway for PrivatBank PayParts (Оплата частинами), payparts v2 API
Package info
github.com/sol-parts/payum-privatbank-payparts
pkg:composer/sol-parts/payum-privatbank-payparts
Requires
- php: >=8.2
- ext-json: *
- ext-mbstring: *
- payum/core: ^1.7
- php-http/discovery: ^1.14
- psr/http-factory: ^1.0
- psr/http-message: ^1.1|^2.0
Requires (Dev)
- nyholm/psr7: ^1.8
- phpunit/phpunit: ^11.5
Suggests
- sol-parts/payum-contracts: Dispatch the shared DoCapture request to confirm (finalize) held payments
README
Provides PrivatBank PayParts («Оплата частинами», payment by installments) integration for Payum, built on the payparts v2 API.
Supported operations:
Capture— create an installment payment and redirect the customer to the bank checkout page.Authorize— create aholdpayment; the customer confirms it, the store captures or cancels it later.DoCapture(the shared request fromsol-parts/payum-contracts, when installed) — confirm (finalize) a held payment via the paypartsconfirmcall;Api::paymentConfirm()is also available directly.Cancel— cancel a held payment.Refund— full refund via the paypartsdeclinecall.Notify— the callback body is never trusted: the payment state is re-fetched from the bank API before the transaction is updated.GetStatus— maps payparts payment states to Payum statuses, includingLOCKED(authorized) and refund detection.
Payment flow
sequenceDiagram
autonumber
actor C as Customer
participant S as Store
participant P as PayParts
C->>S: Places an order
S->>P: Capture — create the payment
P-->>S: Checkout token
S-->>C: Redirect to the PayParts checkout page
C->>P: Picks the number of instalments, confirms with OTP
P-->>S: Returns the customer to redirectUrl
P->>S: Callback to responseUrl
S->>P: Sync — fetch the payment state
P-->>S: Authoritative payment state
S-->>C: Order result page
Note over S,P: The callback body is never trusted:<br/>the state always comes from the API
Loading
Authorize follows the same path but creates a hold payment, so the money is
locked instead of charged and the store settles it later:
sequenceDiagram
autonumber
actor C as Customer
participant S as Store
participant P as PayParts
C->>P: Confirms the hold payment
P->>S: Payment state LOCKED — authorized
Note over S: Goods shipped, or the order is dropped
S->>P: DoCapture — confirm, or Cancel
P-->>S: SUCCESS or CANCELED
Loading
Installation
composer require sol-parts/payum-privatbank-payparts
Usage with PayumBuilder
use Payum\Core\GatewayFactoryInterface; use Payum\Core\PayumBuilder; use SolParts\PayumPrivatbankPayparts\PrivatbankPaypartsGatewayFactory; $payum = (new PayumBuilder()) ->addGatewayFactory('privatbank_payparts', static function (array $config, GatewayFactoryInterface $coreGatewayFactory) { return new PrivatbankPaypartsGatewayFactory($config, $coreGatewayFactory); }) ->addGateway('privatbank_payparts', [ 'factory' => 'privatbank_payparts', 'storeId' => 'your-store-id', 'password' => 'your-store-password', 'partsCount' => 4, ]) ->getPayum();
Usage with Symfony PayumBundle
Register the gateway factory:
# config/services.yaml services: app.privatbank_payparts_gateway_factory: class: Payum\Core\Bridge\Symfony\Builder\GatewayFactoryBuilder arguments: [SolParts\PayumPrivatbankPayparts\PrivatbankPaypartsGatewayFactory] tags: - { name: payum.gateway_factory_builder, factory: privatbank_payparts }
Configure the gateway:
# config/packages/payum.yaml payum: gateways: privatbank_payparts: factory: privatbank_payparts storeId: '%env(PAYPARTS_STORE_ID)%' password: '%env(PAYPARTS_PASSWORD)%' partsCount: 4
Options
| Option | Required | Description |
|---|---|---|
storeId |
yes | Store identifier from the PayParts merchant portal. |
password |
yes | Store password, used to sign every API request. |
partsCount |
no | Default number of installments (2–6), applied when the payment details do not carry one. Defaults to 2. |
Payment details
ConvertPaymentAction fills orderId, amount (decimal string) and
merchantType from the Payum payment. The create request body is built from a
whitelist of payparts protocol fields (orderId, amount, partsCount,
merchantType, products, responseUrl, redirectUrl), so any extra keys
stored in the transaction details never reach the bank.
products is an optional list of {name, count, price} items; item prices are
decimal strings and participate in the request signature.
Caveats
- PayParts never frees a used
orderId: if thecreateresponse is lost, the checkout token cannot be recovered and the sameorderIdcannot be reused. Retry the payment with a new order number instead. - The redirect URL is baked into the payment on
createand cannot be changed afterwards, so it is attached to the long-lived after-URL token rather than the one-time capture token.
License
Released under the MIT License.