Abbonamenti con Stripe per PrestaShop

Hook e API degli Abbonamenti con Stripe per PrestaShop

Per ora questo documento è in inglese.

For module developers who need to know what happens to a subscription (grant or remove a service, notify an external system) or to subscribe a customer from outside the product page. Using the module from the back office is covered in the manual.

The classes on this page are static and their signatures do not change once published. Before using them, load the module with Module::getInstanceByName('bksubscriptions') and check it is active.

The subscription hooks receive

Every action hook receives subscription: the subscription row in the shop, with its lines in lines. The most used fields are id_bk_subscription, id_customer, id_shop, status, currency, link_module and link_ref (the other module’s object it is linked to, if any).

actor, in the hooks that carry it, says who made the change: customer, merchant, stripe or system.

Action hooks

Hook When Besides subscription
actionBkSubscriptionCreated Paid sign-up or return id_order, reactivated, id_reactivated_from, backfill_periods
actionBkSubscriptionRenewed Renewal charged id_order, stripe_invoice, amount, period_end
actionBkSubscriptionPaymentFailed Charge declined stripe_invoice, attempt_count, next_attempt (empty: Stripe no longer retries), amount, error
actionBkSubscriptionCanceled Ended: it will not be charged again reason
actionBkSubscriptionPaused Pause or skipped delivery periods, resumes_at (first charge after the pause), actor
actionBkSubscriptionResumed End of the pause requested by someone actor
actionBkSubscriptionAddressChanged Shipping or billing address, or carrier type (delivery, invoice, carrier), old, new, actor

The hooks are registered when the module is installed and updated, so your module can hook into them even before they have fired.

public function hookActionBkSubscriptionRenewed(array $params)
{
    $subscription = $params['subscription'];
    if ($subscription['link_module'] === $this->name) {
        // Extend the linked object's service until $params['period_end']
    }
}

Hooks that ask

They are called with Hook::exec(..., $arrayReturn = true) and only the answer of the module being asked counts.

actionBkSubscriptionLinkCheck

Before a subscription linked to an object of your module goes into the cart. It receives id_customer, id_product, id_product_attribute, link_module and link_ref. Answer:

Key What it is
ok true if the customer can subscribe to that object
title The text the customer sees under the product name (what tells it apart: their shop, their domain…)
backfill_periods Missed periods charged today (at most the plan’s)
paid_until Optional, YYYY-MM-DD: the object is already paid until that day; nothing is charged today and the first charge is that day
returning Optional: it is a return, and carries the plan’s return fee
message The reason, if ok is false

actionBkSubscriptionPresent

To add rows to the subscription card in “My subscriptions” and on its back office page. It receives subscription and back_office. Answer a list of rows ['label' => …, 'value' => …, 'url' => …]; with back_office the link should lead to the merchant’s screen.

Subscribe a customer from outside the product page

With a form: a POST to module-bksubscriptions-subscribe with token (the customer’s), id_product, id_product_attribute and, optionally, link_module, link_ref, back (the shop URL to return to if it cannot be done) and renew (0: the period is paid and it ends on its own). The module puts the line in the cart and goes to the checkout; if it cannot, it returns to back with the reason. To render it:

$form = Module::getInstanceByName('bksubscriptions')
    ->subscribeForm($idProduct, $idProductAttribute, $this->name, $ref, $backUrl);
// ['action' => url, 'fields' => [name => value, …]]

In PHP: BkSubscriptionsCart::subscribe(Cart $cart, $idProduct, $idProductAttribute, $linkModule, $linkRef, $renews = true) returns ['ok' => bool, 'error' => not_subscription|already_active|link_refused|cart, 'message' => string].

  • With a link, it asks your module first through actionBkSubscriptionLinkCheck.
  • Each linked object is a single cart line with one unit and its own price for today (missed periods at the renewal price and the return fee if it is a return). Asking again for the same object replaces its line.
  • An object with a subscription in service does not accept another one.
  • Once paid, the subscription is created with link_module and link_ref, and the hooks carry them.

Other pieces to build the purchase:

  • BkSubscriptionsCart::customerCart(Context $context): the customer’s current cart, or a fresh one.
  • BkSubscriptionsCart::reactivate(Cart $cart, BkSubscriptionsSubscription $old): puts the return to an ended subscription in the cart; BkSubscriptionsCart::returnQuote($old, $idCurrency) says what it will cost today (today, backfill, return_fee).
  • BkSubscriptionsCart::saveLink($idCart, $idProduct, $idProductAttribute, $fields): ties a cart line as an add-on of another (parent_product, parent_product_attribute) or to an object (link_module, link_ref, link_title, backfill_periods), with what is already paid (prepaid_periods, paid_until, renews).
  • BkSubscriptionsBilling::link($subscription, $linkModule, $linkRef): links a subscription born without a link to an object of yours (for example, from actionBkSubscriptionCreated).

Change plan

BkSubscriptionsBilling::changeLine($subscription, $idLine, $idProduct, $idProductAttribute, $actor) swaps a line of a subscription in service for another product or combination with a plan of the same period (more units, another tier), from the next charge and without proration. It throws PrestaShopException with no_plan or line_not_found.

Read

Method Returns
BkSubscriptionsSubscription::forLink($module, $ref) The subscription serving that object or, if none, the latest one
BkSubscriptionsSubscription::forOrder($idOrder) [['subscription', 'period', 'kind' => new\|renewal\|reactivate]]
BkSubscriptionsSubscription::recurringLinesOf($idOrder) The order lines that renew, [[id_product, id_product_attribute]]
BkSubscriptionsCart::checkoutRow($idCart)['kind'] Whether that cart’s order is a sign-up (new) or a renewal (renewal); it exists before the order is validated
(new BkSubscriptionsPresenter($module, $context))->present($subscription, false) The subscription worded as the customer sees it: status, what happens next, amount per period

Plans

  • BkSubscriptionsPlan::upsertFor($idProduct, $idProductAttribute, $idShop, array $data, $managedBy = ''): creates or updates the plan of a product or combination (interval_unit, interval_count, trial_days, min_periods, total_periods, pause_max_periods, backfill_max, shipping_mode, addon_only, active, separate and prices per currency with renewal_price, setup_fee and return_fee). Fields you leave out are kept. With $managedBy, the plan belongs to your module and the product page shows it read-only.
  • BkSubscriptionsPlan::removeFor($idProduct, $idProductAttribute, $idShop, $managedBy): only deletes a plan owned by that module.
  • BkSubscriptionsPlan::exportFor($idProduct, $idProductAttribute, $idShop): the plan as an array, or null.
  • BkSubscriptionsPlan::addonsFor($idProduct, $idProductAttribute, $idShop) and setAddonsFor($idProduct, $idShop, $addons): a product’s recurring add-ons.

Customer actions from another module

Keeping a cancelled subscription, pausing or coming back are done by the customer in “My subscriptions” (anchor #bksub-<id>). Your module can render the button with a POST to module-bksubscriptions-account (bksub_action = keep, id_subscription, token), which performs the action and returns to the card with its message. For the payment card, a link to module-bksubscriptions-account#bksub-payment.

For themes

$modules.bksubscriptions.account_link (url, title, active) lets a theme render the “My subscriptions” link wherever it likes; in that case it calls the account hook with bksub_in_theme=true so the module does not repeat it. The accent colour of “My subscriptions” is the CSS variable --bksub-accent.

Raccontaci di cosa ha bisogno la tua attività

Un modulo, un’app, un server che dà problemi o qualcosa di urgente. Ti rispondiamo entro 24 ore, con un preventivo chiuso con prezzo e data.