Tovább a tartalomhoz

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ó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' );
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 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:

  1. Ha az $this->auto_renew hamis, egyszeri tranzakciót kell feldolgozni az $this->initial_amount összeggel.

  2. Ha az $this->auto_renew igaz, 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' );
  3. 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 állapotot complete-re:

    $rcp_payments_db->update( $this->payment->id, array(
    'transaction_id' => 'your_transaction_id_here',
    'status' => 'complete'
    ) );
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:

  1. Meg kell mondani a fizetési szolgáltatónak, melyik címre küldje a webhookot.
  2. 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.

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:

  1. A listener ellenőrzése, naplózás az rcp_log() függvénnyel.
  2. A POST-adatok bekérése az rcp_ipn_post szűrőn át (így módosítható).
  3. A tagság megkeresése: előbb a recurring_payment_id alapján (rcp_get_membership_by( 'gateway_subscription_id', … )), ennek hiányában a custom mezőben tárolt tagságazonosítóval (rcp_get_membership()). Ha nincs tagság, a feldolgozás leáll.
  4. 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ó).
  5. Az rcp_valid_ipn akció lefuttatása.
  6. 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 az rcp_webhook_recurring_payment_profile_created és az rcp_gateway_payment_processed akció.
    • 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ása renewal tranzakciótípussal, majd az rcp_ipn_subscr_payment, rcp_webhook_recurring_payment_processed és rcp_gateway_payment_processed akciók.
    • recurring_payment_profile_cancel: ha a kezdő fizetés sikertelen volt, a tagság visszaáll „pending” állapotba, és lefut az rcp_registration_failed és az rcp_paypal_express_initial_payment_failed akció. 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 és recurring_payment_suspended_due_to_max_failed_payment: ha a tagság nem lemondott, „expired” lesz; lefut az rcp_ipn_subscr_failed és az rcp_recurring_payment_failed akció.
    • 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.

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.

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:

Tiszteletben tartjuk a magánszférádat

Sütiket használunk a böngészési élmény javítására és a forgalom elemzésére. Az analitika csak akkor indul, ha engeded. Adatvédelmi irányelvek, Sütitájékoztató.

Sütibeállítások