Fizetési átjáró API
Saját fizetési átjáró írása: regisztrálás, az RCP_Payment_Gateway osztály metódusai, regisztráció feldolgozása, webhookok, tagságok és fizetések kezelése.
A bővítmény teljes fizetési átjáró API-t kínál, amellyel további fizetési szolgáltatókat köthetsz be. Egy átjáró két részből áll: regisztrálni kell, és létre kell hozni az RCP_Payment_Gateway osztály egy leszármazottját. Ez egyéni kód, a saját felelősségedre dolgozz vele.
Az átjáró regisztrálása
Szekció neve “Az átjáró regisztrálása”Az átjárókat az rcp_payment_gateways szűrő regisztrálja. A szűrő egyetlen paramétert, a $gateways tömböt kapja, amely az eddig regisztrált átjárókat tartalmazza. Minden átjáró egy tömb a következő kulcsokkal:
| Kulcs | Jelentése |
|---|---|
class |
Az RCP_Payment_Gateway osztályt kiterjesztő osztály neve. |
label |
A fizetési mód felirata, amelyet a vásárló lát. |
admin_label |
Az átjáró megnevezése a beállítások képernyőn. |
Az átjáró azonosítója a fő tömbben használt kulcs.
function pw_rcp_register_2checkout_gateway( $gateways ) {
$gateways['2checkout'] = array( 'label' => '2Checkout', 'admin_label' => '2Checkout Redirect', 'class' => 'RCP_Payment_Gateway_2Checkout' );
return $gateways;}add_filter( 'rcp_payment_gateways', 'pw_rcp_register_2checkout_gateway' );Az alaposztály metódusai
Szekció neve “Az alaposztály metódusai”| Metódus | Kötelező? | Mire való |
|---|---|---|
init() |
igen | Az átjáró tulajdonságainak beállítása, például API-kulcsok és végpontok. |
process_signup() |
igen | Akkor fut le, amikor a regisztrációs űrlapot elküldik és minden ellenőrzés sikerült. Itt történik a fizetés és/vagy az előfizetés létrehozása az átjárónál. |
process_webhooks() |
nem | A fizetési szolgáltató webhookjainak felismerése és feldolgozása, jellemzően a megújításokhoz. |
scripts() |
nem | Az átjáróhoz szükséges JS/CSS betöltése vagy kiírása. |
fields() |
nem | Átjáró-specifikus mezők kiírása a regisztrációs űrlapon. |
validate_fields() |
nem | Az átjáró saját mezőinek ellenőrzése. |
Egy átjárónak csak az init() és a process_signup() kötelező, de a legtöbb a többit is használja.
Az osztály inicializálása (init())
Szekció neve “Az osztály inicializálása (init())”Az init() főleg arra való, hogy megadd, milyen funkciókat támogat az átjáró, és hogy lekérdezd a teszt (sandbox) módot.
public function init() { global $rcp_options;
$this->supports[] = 'one-time'; $this->supports[] = 'recurring'; $this->supports[] = 'fees'; $this->supports[] = 'trial';
if ( $this->test_mode ) { $this->api_login_id = isset( $rcp_options['authorize_test_api_login'] ) ? sanitize_text_field( $rcp_options['authorize_test_api_login'] ) : ''; $this->transaction_key = isset( $rcp_options['authorize_test_txn_key'] ) ? sanitize_text_field( $rcp_options['authorize_test_txn_key'] ) : ''; $this->transaction_signature = isset( $rcp_options['authorize_test_signature_key'] ) ? sanitize_text_field( $rcp_options['authorize_test_signature_key'] ) : ''; } else { $this->api_login_id = isset( $rcp_options['authorize_api_login'] ) ? sanitize_text_field( $rcp_options['authorize_api_login'] ) : ''; $this->transaction_key = isset( $rcp_options['authorize_txn_key'] ) ? sanitize_text_field( $rcp_options['authorize_txn_key'] ) : ''; $this->transaction_signature = isset( $rcp_options['authorize_signature_key'] ) ? sanitize_text_field( $rcp_options['authorize_signature_key'] ) : ''; }
require_once RCP_ANET_PATH . 'vendor/autoload.php';}A példa egyszeri fizetést, ismétlődő fizetést, beiratkozási díjat és ingyenes próbaidőt jelez támogatottként. A teszt és az éles API-kulcsok más-más tulajdonságokba kerülnek, végül betöltődik az átjáró SDK-ja.
A regisztráció feldolgozása (process_signup())
Szekció neve “A regisztráció feldolgozása (process_signup())”Itt történik a munka oroszlánrésze: az átjáró API-jának hívása vagy átirányítás egy külső fizetési oldalra. A példában átirányítunk egy külső oldalra:
public function process_signup() {
// A lekérdezési paraméterek összeállítása. $args = array( 'price' => $this->initial_amount, // Kezdő ár + beiratkozási díj - kedvezmények. A szint alapára: $this->amount. 'description' => $this->subscription_name, // A tagsági szint neve. 'custom' => $this->membership->get_id(), // A tagság azonosítója egyedi azonosítóként. 'email' => $this->email, // A felhasználó e-mail-címe. 'return' => $this->return_url // A sikeres regisztráció utáni cím. );
// Automatikus megújítás beállítása, ha kell. if ( $this->auto_renew ) { $args['interval'] = $this->length_unit; // month, day, year $args['interval_count'] = $this->length; // 1, 2, 3 ... }
// Átirányítás a külső fizetési oldalra. wp_redirect( add_query_arg( $args, 'http://paymentpage.com/api/' ) ); exit;}A process_signup() fontos teendői:
-
Ha az
$this->auto_renewhamis, egyszeri tranzakciót kell feldolgozni az$this->initial_amountösszeggel. -
Ha az
$this->auto_renewigaz, ismétlődő előfizetést kell létrehozni az átjárónál. A mai terhelés az$this->initial_amount, a megújításoké az$this->amount. Ha az előfizetés létrejött, mentsd el az átjáró előfizetés-azonosítóját a tagságba:$this->membership->set_gateway_subscription_id( 'gateway_subscription_id_goes_here' ); -
Amikor a kezdő fizetés kifizetettnek bizonyul, frissítsd a függőben lévő fizetésrekordot: add meg a
transaction_idértéket, és állítsd az állapototcomplete-re:$rcp_payments_db->update( $this->payment->id, array('transaction_id' => 'your_transaction_id_here','status' => 'complete') );
Az alaposztály hasznos tulajdonságai
Szekció neve “Az alaposztály hasznos tulajdonságai”| Tulajdonság | Jelentése |
|---|---|
$supports |
A támogatott funkciók tömbje. |
$email |
A vásárló e-mail-címe. |
$user_id |
A vásárló felhasználói azonosítója. |
$user_name |
A vásárló felhasználóneve. |
$currency |
A kiválasztott pénznem kódja (például „USD”). |
$amount |
Az ismétlődő előfizetés összege, az egyszeri díjak és kedvezmények nélkül. |
$initial_amount |
Az első fizetés összege, az egyszeri beiratkozási díjakkal, kedvezményekkel és jóváírásokkal együtt. |
$discount |
A fizetésből levont kedvezmény teljes összege. |
$length |
A tagság időtartama. |
$length_unit |
Az időtartam egysége (day, month vagy year). |
$signup_fee |
Az első fizetésre rakódó beiratkozási díj. Már benne van az $initial_amount értékében. |
$subscription_key |
A tagság egyedi előfizetési kulcsa. |
$subscription_id |
Annak a tagsági szintnek az azonosítója, amelyre a vásárló feliratkozik. |
$subscription_name |
Annak a tagsági szintnek a neve, amelyre a vásárló feliratkozik. |
$auto_renew |
Ismétlődő előfizetésről van-e szó. |
$return_url |
A sikeres regisztráció utáni átirányítás címe. |
$test_mode |
Az oldal teszt (sandbox) módban van-e. |
$payment |
A tranzakció fizetésobjektuma. Az átjáróba érkezéskor „pending” állapotú, sikeres fizetés után „complete”-re kell állítani. |
$customer |
A felhasználó RCP_Customer objektuma. |
$membership |
A függőben lévő tagságrekord RCP_Membership objektuma. |
$subscription_start_date |
Az előfizetés kezdete MySQL formátumban. Alapból üres (ma kezdődik). Ha az első fizetés ingyenes (próbaidő vagy 100% egyszeri kedvezmény), az első fizetés napja lesz. |
Mezők hozzáadása a regisztrációs űrlaphoz (fields())
Szekció neve “Mezők hozzáadása a regisztrációs űrlaphoz (fields())”A fields() visszatérési értékét a bővítmény automatikusan az űrlap végére fűzi, amikor az átjárót kiválasztják. Ez csak átjáró-specifikus mezőkre való. Sok átjárónak bankkártya-űrlap kell, ezt a beépített card-form sablonnal adhatod hozzá:
public function fields() { ob_start(); rcp_get_template_part( 'card-form' ); return ob_get_clean();}Az rcp_get_template_part() a sablonfájl-rendszerrel dolgozik, lásd a sablonfájlok fejezetét. A card-form a bővítmény alap bankkártya-sablonja. További mezőket egyszerűen a fields() metódusba írhatsz.
Mezők ellenőrzése (validate_fields())
Szekció neve “Mezők ellenőrzése (validate_fields())”A hozzáadott mezők ellenőrzésére a validate_fields() való. Hibaüzenetet az add_error() metódussal rögzítesz, ez megjelenik az űrlapon, és megakadályozza a beküldést.
public function validate_fields() { if ( empty( $_POST['rcp_card_number'] ) ) { $this->add_error( 'missing_card_number', __( 'The card number you have entered is invalid', 'rcp' ) ); } if ( empty( $_POST['rcp_card_cvc'] ) ) { $this->add_error( 'missing_card_code', __( 'The security code you have entered is invalid', 'rcp' ) ); } if ( empty( $_POST['rcp_card_zip'] ) ) { $this->add_error( 'missing_card_zip', __( 'The zip / postal code you have entered is invalid', 'rcp' ) ); } if ( empty( $_POST['rcp_card_name'] ) ) { $this->add_error( 'missing_card_name', __( 'The card holder name you have entered is invalid', 'rcp' ) ); } if ( empty( $_POST['rcp_card_exp_month'] ) ) { $this->add_error( 'missing_card_exp_month', __( 'The card expiration month you have entered is invalid', 'rcp' ) ); } if ( empty( $_POST['rcp_card_exp_year'] ) ) { $this->add_error( 'missing_card_exp_year', __( 'The card expiration year you have entered is invalid', 'rcp' ) ); }}Webhookok feldolgozása (process_webhooks())
Szekció neve “Webhookok feldolgozása (process_webhooks())”A webhook értesít arról, hogy megtörtént egy előfizetési fizetés, vagy a kereskedői fiókban módosult egy előfizetés. Két részből áll:
- Meg kell mondani a fizetési szolgáltatónak, melyik címre küldje a webhookot.
- A bővítményben fel kell dolgozni az érkező kérést.
A cím megadásának módja szolgáltatónként eltér, gyakran egy paraméter az előfizetés létrehozásakor. A PayPal például a notify_url paraméterrel dolgozik. A webhook címe nem más, mint az oldal főcíme egy különleges lekérdezési paraméterrel, amellyel megkülönböztethető egy sima oldallekéréstől:
public function process_signup() { $args = array( 'price' => $this->initial_amount, 'description' => $this->subscription_name, 'custom' => $this->membership->get_id(), 'email' => $this->email, 'return' => $this->return_url, 'notify_url' => add_query_arg( 'listener', 'my_gateway_id', home_url( 'index.php' ) ) ); if ( $this->auto_renew ) { $args['interval'] = $this->length_unit; $args['interval_count'] = $this->length; } wp_redirect( add_query_arg( $args, 'http://paymentpage.com/api/' ) ); exit;}A feldolgozás a process_webhooks() metódusban történik:
public function process_webhooks() { // Webhook-e a kérés? if ( ! isset( $_GET['listener'] ) || strtoupper( $_GET['listener'] ) != 'my_gateway_id' ) { return; } // Itt olvasd ki a webhook adatait a $_POST tömbből.}A webhook alatt ellenőrizni és tisztítani kell az adatokat, majd a szükséges módosításokat el kell végezni a vásárló fiókján. Jellemző teendők:
- fiók aktiválása,
- előfizetés megújítása,
- fizetés rögzítése,
- előfizetés lemondása.
Példa: a PayPal Express webhookja
Szekció neve “Példa: a PayPal Express webhookja”A beépített PayPal Express átjáró így dolgozza fel az értesítéseket. Az átjáró azonosítója az EIPN listener. A lépések:
- A
listenerellenőrzése, naplózás azrcp_log()függvénnyel. - A POST-adatok bekérése az
rcp_ipn_postszűrőn át (így módosítható). - A tagság megkeresése: előbb a
recurring_payment_idalapján (rcp_get_membership_by( 'gateway_subscription_id', … )), ennek hiányában acustommezőben tárolt tagságazonosítóval (rcp_get_membership()). Ha nincs tagság, a feldolgozás leáll. - A tagsági szint és a felhasználó azonosítása, a fizetési adatok tömbjének összeállítása (szint neve, fizetéstípus, előfizetési kulcs, felhasználó, ügyfél, tagság, állapot
complete, az átjáró azonosítója, összeg, dátum, tranzakcióazonosító). - Az
rcp_valid_ipnakció lefuttatása. - A tranzakció típusa (
txn_type) szerinti ág:recurring_payment_profile_created: a kezdő fizetés rögzítése. Ha van függő fizetés, azt frissíti (ez aktiválja a tagságot), különben új fizetést szúr be és megújítja a tagságot. Lefut azrcp_webhook_recurring_payment_profile_createdés azrcp_gateway_payment_processedakció.recurring_payment: elmentik az előfizetés azonosítóját. Sikertelen vagy függő fizetésnél jegyzet kerül a tagságra és a feldolgozás megáll. Sikeres fizetésnél$membership->renew( true ), a fizetés beszúrásarenewaltranzakciótípussal, majd azrcp_ipn_subscr_payment,rcp_webhook_recurring_payment_processedésrcp_gateway_payment_processedakciók.recurring_payment_profile_cancel: ha a kezdő fizetés sikertelen volt, a tagság visszaáll „pending” állapotba, és lefut azrcp_registration_failedés azrcp_paypal_express_initial_payment_failedakció. Egyébként (kivéve a lezárult fizetési tervet) a tagság lemondottá válik, de a hozzáférés a futamidő végéig megmarad ($membership->cancel(),rcp_ipn_subscr_cancel,rcp_webhook_cancel).recurring_payment_failedésrecurring_payment_suspended_due_to_max_failed_payment: ha a tagság nem lemondott, „expired” lesz; lefut azrcp_ipn_subscr_failedés azrcp_recurring_payment_failedakció.web_accept: „completed” állapotnál a fizetés beszúrásra kerül (ha a tranzakció még nem létezik); „denied”, „expired”, „failed” vagy „voided” állapotnál az aktív tagság lemondásra kerül.
Tagságok módosítása
Szekció neve “Tagságok módosítása”Az átjáró feladata a felhasználói előfizetések módosítása is (lemondás, aktiválás, fizetések). Ehhez az RCP_Membership osztály ad segítséget. Példányosítás:
$membership = rcp_get_membership( $membership_id );Ha az átjáró előfizetés-azonosítója megvan, abból is lekérhető a tagság:
$membership = rcp_get_membership_by( 'gateway_subscription_id', 'your_gateway_subscription_id' );Ezután hívhatod az osztály nyilvános metódusait. Megújításkor (például ha beérkezett egy fizetés):
$membership->renew( true );A true jelzi, hogy az előfizetés ismétlődő. Ha nem az, false-t adj meg. A renew() a tagsági szint alapján magától kiszámítja és beállítja a lejárati dátumot. Lemondás:
$membership->cancel();Az első aktiválás általában a függő fizetés teljesítésével történik: ha a függő fizetés állapotát „complete”-re állítod, a hozzá tartozó tagság automatikusan aktiválódik.
Fizetések rögzítése
Szekció neve “Fizetések rögzítése”Az átjárónak rögzítenie kell a fizetéseket, hogy megjelenjenek a Restrict → Payments oldalon. A kezdő fizetést jellemzően a regisztrációkor, az ismétlődőket a webhook feldolgozásakor rögzíted. Ehhez az RCP_Payments osztály kell:
$membership = rcp_get_membership( $membership_id );$payments = new RCP_Payments();$args = array( 'date' => date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ), // A fizetés dátuma 'subscription' => $membership->get_membership_level_name(), // A tagsági szint neve 'object_id' => $membership->get_object_id(), // A tagsági szint azonosítója 'payment_type' => 'Credit Card', // Fizetéstípus (főleg visszamenőleges kompatibilitás miatt) 'gateway' => 'my_gateway_id', // Az átjáró azonosítója 'subscription_key' => $membership->get_subscription_key(), // Előfizetési kulcs 'amount' => $amount, // Teljes összeg 'subtotal' => $subtotal, // Részösszeg 'credits' => $credits, // Alkalmazott jóváírások 'fees' => $fees, // Beiratkozási díjak 'discount_amount' => $discount_amount, // Kedvezmény összege 'discount_code' => $discount_code, // Használt kedvezménykód 'user_id' => $membership->get_customer()->get_user_id(), // A fizető felhasználó azonosítója 'customer_id' => $membership->get_customer()->get_id(), // Az ügyfél azonosítója 'membership_id' => $membership->get_id(), // A tagság azonosítója 'transaction_type' => 'new', // new, upgrade, downgrade vagy renewal 'transaction_id' => $transaction_id, // Az átjáró tranzakcióazonosítója 'status' => 'complete', // complete, pending vagy failed);$payments->insert( $args );Az egyes értékeket neked kell megadnod, általában a webhook POST-adataiból vagy az API válaszából. A függő fizetést is teljesítheted, ha megvan a tagságobjektum, mert a függő fizetés azonosítója ott van eltárolva:
$payments = new RCP_Payments();$pending_payment_id = rcp_get_membership_meta( $membership->get_id(), 'pending_payment_id', true );
if ( ! empty( $pending_payment_id ) ) { $payment_data = array( 'status' => 'complete' ); // A frissítendő adatok $payments->update( absint( $pending_payment_id ), $payment_data );}Amikor a függő fizetés teljesül, a tagság automatikusan aktiválódik, a vásárló hozzáférést kap, és megkapja az aktív tagság e-mailt (ha be van állítva).
Készült: