Recurring charging of credit cards is a convenient solution for the customer and the seller

This tutorial will help you understand the mechanism of this type of payment and help you implement it correctly on your own website. Recurring payments can be used for subscription or on-demand payments, without the need to re-enter card details.


  1. Merchant Account - register
  2. Enabled Credit Card payments (currently with Elavon)

The mechanism of payment by remembered card

Allowing to start collecting money without having to enter data requires the card to be saved by making a one-time payment of any amount. In the article "Implementation of the card payment gateway on the store's website" we have described the method of implementing the card gateway used to process the first card charge.

With a saved payment card token, you can try to charge it again in many situations, for example:

  • Providing the payment option with a saved card (online stores)
  • Before or after a service
  • Before sharing multimedia content
  • After the paid subscription period


  1. Whenever there is a need to charge a customer card, simply generate a transaction in a specific currency and amount, and then try to execute charge.
  2. If the customer has enough funds and restrictions on online transactions allow for proper charge, the whole process takes place within seconds.
  3. In case of failure, our system returns the appropriate information that can be passed on to the client and/or attempt to pay for the transaction later.
  4. The information about the successful charge returned by the Tpay system is binding and it can be concluded that the funds will be correctly transferred to the seller's account.
  5. At the moment there is no possibility to pre-authorize funds on the card. You can only charge the expected amount and then return the difference.

Technical explanation of recurring payments

  1. Execution of the transaction with a saved card requires the earlier implementation of the secure sale method, which implementation we have described in the article "Implementation of the card payment gateway on the store's website" or register sale method.
  2. When you have a token (parameter "cli_auth"), which is a random string representing the connection between the payment card and the seller's account in the Tpay system, you must prepare the transaction.
  3. The unpaid transaction should be generated using the presale API method. In case of payment failure, there is no need to generate new one if the order remains the same.
    Example of presale parameters:
      "desc": "payment for order xyz",
      "cli_auth": "t59c2810d59285e3e0ee9d1f1eda1c2f4c554e24",
      "amount": 10.99,
      "api_password": "XtCns9OAue8zSFJ",
      "sign": "1355b3d2584af8a1fa44573171d25b316ef16b4f",
      "currency": 985,
      "order_id": 32145,
      "language": "pl"
  4. The transaction identifier generated by this method (the "sale_auth" parameter in the response) should be passed to the sale method, which will make an attempt to execute the charge:
      "cli_auth": "t59c2810d59285e3e0ee9d1f1eda1c2f4c554e24",
      "sale_auth": "t59c28295aeb071b0cf6471b24f727f6456998de",
      "api_password": "XtCns9OAue8zSFJ",
      "sign": "231f533d91cf3ec6ce5d02d672beb4b127e1e987"
  5. The information returned in the response is a confirmation of successful or failure charge. In the case of failure, the returned "reason" parameter will contain the rejection code, which can be compared with this table and passed to the client (for example if the payment limit is too low).
  6. You can perform more attempts later by repeating the sale method for the same transaction identifier.
  7. provides ready to use PHP libraries in which making payments with a token is very easy! Check the recurring payment example on

Example of implementation based on PHP Tpay libraries

In this tutorial: Example of credit card gateway implementation based on PHP Tpay libraries we have described the creation of two classes that are responsible for the first card payment and receiving notification of a payment. When we start the integration of recurring payments, we assume that in the database of the store a given user has already been assigned a minimum of one payment card token.

  1. Download Tpay libraries from
  2. Create a file RecurrentPayment.php (eg in the examples folder) extending the PaymentCard class, in which constructor enter your API access data:
    namespace tpayLibs\examples;
    use tpayLibs\src\_class_tpay\PaymentCard;
    include_once 'config.php';
    include_once 'loader.php';
    class RecurrentPayment extends PaymentCard
        private $transactionId = null;
        public function __construct()
            $this->cardApiKey = 'bda5eda723bf1ae71a82e90a249803d3f852248d';
            $this->cardApiPass = 'IhZVgraNcZoWPLgA';
            $this->cardVerificationCode = '6680181602d396e640cb091ea5418171';
            $this->cardHashAlg = 'sha1';
  3. Create a control function that will enter basic transaction data and prepare an unpaid presale transaction. At this point, we assume that the Client Token downloaded from the customer's database will be forwarded
    public function init(
            $orderId = null,
            $currency = 985,
            $language = 'pl'
        ) {
            //Prepare an unpaid transaction
            $transaction = $this->presaleMethod($saleDescription);
            $this->transactionId = $transaction['sale_auth'];
            return $this;
  4. Create a function that will try to execute the charge and your own setOrderAsConfirmed function, which will update the transaction status in your database:
    public function payBySavedCreditCard()
        //Try to execute payment
        //In test mode this method has 50% probability of success
        $result = $this->saleMethod($this->transactionId);
        if (isset($result['status']) && $result['status'] === 'correct') {
            //Charge was successfull, mark order as paid
            return $this->setOrderAsConfirmed();
        } else {
            //Log rejection code
            return $result['reason'];
  5. At the end of the file, just add a call with input parameters, eg to download PLN 12.50 from a saved client card, just call:
    (new RecurrentPayment())
        ->init('payment for order xyz', 't5a96d292cd0a5c63a14c30adeae55cb200df087', 12.50, 'order_123456', 985, 'pl')
  6. This mechanism is now ready to be called whenever you need to charge the payer's account, for example, a subscription or other fee, because the amount may be different from the amount of the original transaction.
    • In the simplest (not recommended) model, you can use the CRON mechanism, which will call our file encapsulated in additional conditions required in your system (such as verification, whether the customer's account is still active), eg once a month.
    • Of course, for each charge, the input data of the init() function should take the values you want to debit the payer's account, in this case, we used the sample data.
    • After each charge, the customer receives the notification email from containing a link to his card deregistration, preventing the next payment.
    • If your system collects the fee incorrectly, simply make the refund on the Merchant Panel.