logo
Find anything /
API Reference Sign In β†’

Getting Started

YouCan Pay offers an easy way to receive credit card payment in your application. In this guide we'll see how to get started quickly. To follow along, you need to have an account in YouCan Pay for integration keys.

YouCan Pay SDK: https://github.com/youcan-shop/youcan-payment-php-sdk

Private and Public keys

Private and public keys are used to secure the communication between your application and YouCan Pay. You can find your keys by logging to your account and navigating to settings. The keys are prefixed by pri_xxx and pub_xxx to help distinguish between the two.
Note:

Be careful, your private key should never be exposed or shared with anyone.

Payment Flow

To better understand the payment flow, the diagram on the right illustrates the different steps to complete a payment by your customer through YouCan Pay.

Steps


Tokenization

When the customer arrive to the payment page, and you want to display the YouCan Pay form you need to generate a token for the current transaction. This token will allow you encapsulate you order info (amount, currency, order ID, etc)


Form Display

In this step, you include the JS and HTML for display for credit card form where the user will input his card info.


Start Payment

When the customer click on the pay button, a request will be sent to YouCan Pay server to process the payment.
If the customer card has 3DS enabled, he will be redirected to the bank page to validate the transaction and come back to YouCan Pay server. If the customer card doesn't have 3DS enabled, YouCan Pay will process the transaction directly.


Payment Processed

When the transaction is processed the customer will be redirected to your application. Depending on the transaction status (success/error) it will redirect to the endpoint you defined.

Tokenization

The tokenization is the process of generating a token for your current transaction. This token will hold you order data (order ID, amount, currency). The amount should be in smallest currency unit (e.g., 100 cents to charge $1.00) Since this process is critical, it should be done in your backend using our SDK.

Method Parameters


orderId required

Identifier of the order you want to be paid.


amount required

Integer amount: The amount, Example: 25 USD is 2500.


currency required

Currency: Uppercase currency.


customerIP required

Customer Address IP


successUrl required

This URL is returned when the payment is successfully processed.


errorUrl required

This URL is returned when payment is invalid.


customerInfo optional

Data of the customer who wishes to make this purchase.


metadata optional

You can use it to send data to retrieve after the response or in the webhook.

Command
    
      composer require youcanpay/payment-sdk
    
  
Code
    
      use YouCan\Pay\YouCanPay;

    $youCanPay = YouCanPay::instance()->useKeys('pri_key', 'pub_key');

    // Data of the customer who wishes to make this purchase.
    $customerInfo = [
        'name'         => '',
        'address'      => '',
        'zip_code'     => '',
        'city'         => '',
        'state'        => '',
        'country_code' => '',
        'phone'        => '',
        'email'        => '',
    ];

    $metadata = [
        // Can you insert what you want here...
        //'key' => 'value'
    ];

    // generate a token for a new payment
    $token = $youCanPay->token->create(
        "order-id",
        "2000",
        "USD",
        "123.123.123.123",
        "https://yourdomain.com/orders-status/success",
        "https://yourdomain.com/orders-status/failed",
        $customerInfo,
        $metadata
    );

    echo $token->getId();
    
  

Creating an instance of YCPay

The first step is to include the YouCan Pay JS code in your markup.
When the code is loaded, we're ready to render the payment form using the code snippet on the right.

Constructor Parameters


publicKey required

The seller's YouCanPay account public key. This lets us know who is receiving the payment.


options

Extra configuration options to tailor the integration to your needs.

Child attributes

options.formContainer required

The CSS selector for the container in which we will render the integration. If no container is found, the integration won't render.


options.locale optional

The language in which to display the forms and error messages. Currently supports en, ar, and fr. If no locale is specified, it will be automatically inferred from the browser or fall back to en as a default locale.


options.isSandbox optional

Specified whether or not to run the integration in Sandbox Mode, this is useful for testing your integration. It is recommended to set this to false or omit it entirely in production, as it is false by default.


options.errorContainer optional

The CSS selector for the container in which we will all errors related to the usage of the integration. This is set to "#ycp-error-container" by default. If no container is found, no errors will be displayed.


options.customCSS optional

CSS code to style the integration to your liking.


options.token optional

In case you a single static payment token, you can pass it here in the constructor. By doing so you can not pass it down to the ".pay()" method. Token can be updated using the ".setToken()" method.

Code
    
      <script src="https://youcanpay.com/js/ycpay.js"></script>

    <div id="error-container"></div>
    <div id="payment-container"></div>
    <button id="pay">Pay</button>

    <script type="text/javascript">
        const ycPay = new YCPay('pub_key', {
            formContainer: '#payment-container',
            locale: 'en',
            isSandbox: false,
            errorContainer: '#error-container',
            customCSS: '',
            token: 'token_x6gf0_....'
        });
    </script>
    
  

Form Display

The next step is to render the form in your markup, this is done by using one of the render methods that the instantiated ycPay object provides.

Credit Card Form


YCPay YCPay Instance

Child attributes

YCPay.renderCreditCardForm(theme?)

Renders the Credit Card form. Takes in an optional theme parameter.

This method renders a credit card form directly inside the specified container.

CashPlus Form


YCPay YCPay Instance

Child attributes

YCPay.renderCashPlusForm(theme?)

Renders the CashPlus form. Takes in an optional theme parameter.

This method renders the CashPlus form directly inside the specified container.

Available Gateways


YCPay YCPay Instance

Child attributes

YCPay.renderAvailableGateways(gateways, theme?)

Takes in an array of gateway names as an additional parameters, current supported gateways are "CashPlus", "CreditCard". If an empty array is provided, renders all available gateways for the account. Takes in an optional theme parameter.

Alternatively, if you wish to allow users to select how they want to pay, you could use the renderAvailableGateways() method. If only a single gateway is available, it will be rendered directly without prompting the user to pick a method.

Reset the integration form


YCPay YCPay Instance

Child attributes

YCPay.reset(theme?)

In some cases you might want to refresh the visuals of the form once the payment is done, or perhaps for another use case of yours, for that, this method allows you to do just that.

This method reset the visuals of the currently rendered form.

Update the YCP token


YCPay YCPay Instance

Child attributes

YCPay.setToken(token)

When setting the token from the constructor, you are kind of limited on how you want to handle your payment especially if your token gets updated regularly and you don't have the ability to set it via the ".pay()" method. In that case, you utilize this method to update it, guaranteeing your token always being updated.

This method updates the internal payment token id. Useful when setting the token in the constructor.
Code
    
      <script src="https://youcanpay.com/js/ycpay.js"></script>

    <div id="error-container"></div>
    <div id="payment-container"></div>
    <button id="pay">Pay</button>

    <script type="text/javascript">
        const ycPay = new YCPay('pub_key', {
            locale: 'en',
            isSandbox: false,
            errorContainer: '#error-container',
            formContainer: '#payment-container'
        });

        // render the payment methods
        ycPay.renderAvailableGateways([], 'default')
    </script>
    
  

Start Payment

The tokenId on line 11 is the one generated in the tokenization section. The successCallback is called when the transaction is successful, and you get the final transaction ID that you can submit with your order details. Similarly, errorCallback is called with an error occur during the payment, and you get the error message as a parameter to show to customer.

Congrats, now you're ready to accept payments from customers using YouCan Pay πŸŽ‰.

Code
    
      <script type="text/javascript">
      const ycPay = new YCPay('pub_key', {
          formContainer: '#payment-container',
      });

      // render the form
      ycPay.renderCreditCardForm();

      // start the payment on button click
      document.getElementById('pay').addEventListener('click', function() {
        // execute the payment
        ycPay.pay(tokenId)
          .then(successCallback)
          .catch(errorCallback);
      })

      function successCallback(response) {
        //your code here
      }

      function errorCallback(response) {
        //your code here
      }
    </script>
    
  

Payment Processed

Once the payment is done, you can get the details of the transaction in your backend to validate the amount, order ID, etc.

When the payment is proceeded by a Moroccan card, the transaction currency is converted to MAD. You can get the submitted original amount and currency from getBaseAmount(), getBaseCurrency() in the Transaction object.

Code
    
      use YouCan\Pay\YouCanPay;

    $youCanPay = YouCanPay::instance()->useKeys('pri_key', 'pub_key');

    $transaction = $youCanPay->transaction->get("transaction-id");

    if (is_null($transaction)) {
    // invalid transaction ID
    }

    // fetch your order
    $order = Order::first();

    // the amount is in smallest currency unit
    $amount = $transaction->getBaseAmount() ?? $transaction->getAmount();

    if (bccomp($amount, $order->getAmount()) !== 0) {
    // the YouCan Pay transaction amount is different than the order amount
    }
    
  

Webhooks

YouCan Pay uses webhooks to notify your application when an event happens in your account. Webhooks are useful for handling reactions to asynchronous events on your backend, such as successful payments, failed payments, successful refunds, and many other real time events. A webhook enables YouCan Pay to push real-time notifications to your application by delivering JSON payloads over HTTPS.

These notifications can be used to map YouCan Pay events to suitable reactions on your backend. For example, everytime you receive a notification of a paid transaction, you can programmatically mark an order as paid in your backend and update its information to match the transaction's. You can start receiving webhook notifications by following these steps:

  • Create a public webhook endpoint on your server.
  • Handle requests from YouCan Pay by parsing each event object and returning 2xx response status codes
  • Deploy your webhook endpoint so it’s a publicly accessible HTTPS URL.
  • Register your publicly accessible HTTPS URL in the YouCan Pay webhook settings dashboard.

Event objects

Every time an event is triggered in our system, all of your configured webhooks are automatically notified with a JSON payload of the corresponding event.

Webhook event object


id string

The object's unique identifier.


event_name string

The event type following the pattern of "event_resource.event_action".


sandbox boolean

Whether the event was triggered in a sandbox environment or not.


payload object

An object containing sub-objects pertaining to the event's resource.

Webhook event object
    
      {
    "id": "f9dc2ad2-a2ac-4608-878c-066f5ceb2ab3",
    "event_name": "transaction.paid",
    "sandbox": false,
    "payload": {
      "token": {
        "id": "31b72661-e51f-4cb3-8aec-d990aec3ae63"
      },
      "customer": {
        "id": "e85efd21-7a28-4cfa-9d43-b64355db1292",
        "city": null,
        "name": null,
        "email": null,
        "phone": null,
        "state": null,
        "address": null,
        "zip_code": null,
        "country_code": null
      },
      "metadata": {
        "type": "checkout",
        "cart.id": "uuid"
      },
      "transaction": {
        "id": "5d47a625-4e1e-4505-94e0-8328a371fe67",
        "amount": "500",
        "status": 1,
        "currency": "MAD",
        "order_id": "12",
        "created_at": "2022-05-13T10:36:08.000000Z",
        "base_amount": null,
        "base_currency": null
      },
      "payment_method": {
        "id": 1,
        "card": {
          "id": "2c546131-e228-44e0-8fb4-733d6dd9daa7",
          "brand": "VISA",
          "fingerprint": "1f3decbcf2fb9a2e50e8a64ec5b2c83e",
          "last_digits": "1881",
          "country_code": "MA",
          "is_3d_secure": false
        },
        "name": "credit_card"
      }
    }
  }
    
  

Standalone Integration

Standalone integration is another way of using YouCan Pay. The main difference from the widget integration is that the payment is done completely on YouCan Pay and the customer gets redirected back to your platform when done. Here's how all of this works:

  • Generate a token for the current transaction.
  • Redirect the customer to YouCan Pay with this token.
  • The customer is redirected back to your platform after payment is done.

Generate Token

When generating a token, you can specify the return URL for success and error. And from that point you can show the appropriate response for the customer.
Command
    
      composer require youcanpay/payment-sdk
    
  
Code
    
      use YouCan\Pay\YouCanPay;

    $youCanPay = YouCanPay::instance()->useKeys('pri_key', 'pub_key');

    // generate a token for a new payment
    $token = $youCanPay->token->create(
    "order-id",
    "2000",
    "USD",
    "123.123.123.123",
    "https://mywebsite.com/success_callback",
    "https://mywebsite.com/error_callback"
    );
    
  

Redirect Customer

Now that we have a token, we can redirect the user from the backend or give him a link to follow.
Code
    
      // redirect automatically
    header(sprintf("Location:%s", $token->getPaymentURL()));

    // or, return a link for the customer to click on
    echo sprintf('Complete your order', $token->getPaymentURL());
    
  

Sandbox

YouCan Pay Sandbox offers an easy way for developers to test YouCan Pay in their test environment.

Note:

Note: when trying to switch to the sandbox mode, you need to always use the sandbox keys that you can find on the settings page, which have the following format: pub_sandbox_xxx and pri_sandbox_xxx

Set up YouCan Pay Sandbox

The sandbox mode in YouCan Pay is an option that can be enabled by using ycPay.setSandboxMode(true) in the Javascript integration
Code
    
      <script src="https://youcanpay.com/js/ycpay.js"></script>

    <div id="error-container"></div>
    <div id="payment-container"></div>
    <button id="pay">Pay</button>

    <script type="text/javascript">
      const ycPay = new YCPay('pub_sandbox_key', {
          formContainer: '#payment-container',
          locale: 'en',
          isSandbox: true,
          errorContainer: '#error-container',
      });
    </script>
    
  

Testing and test cards

After the integration, the payment form will be rendered in the the specified div element with the following badge to indicate being in the sandbox mode: Test Mode

If the card used is protected by 3DS, a confirmation will pop, which simulates the 3DS verification process that will be shown to the customer in the live mode.

You can use the test cards below in sandbox mode.

Card CVV Date Behaviour
4242 4242 4242 4242
112
10/24
No 3DS - Success
4000 0000 0000 3220
112
10/24
3DS - Success
4000 0084 0000 1629
112
10/24
3DS - Card Rejected
4000 0000 0000 0077
112
10/24
No 3DS - No Funds
Code
    
      <script src="https://youcanpay.com/js/ycpay.js"></script>

    <div id="error-container"></div>
    <div id="payment-container"></div>
    <button id="pay">Pay</button>

    <script type="text/javascript">
      const ycPay = new YCPay('pub_sandbox_key', {
          formContainer: '#payment-container',
          locale: 'en',
          isSandbox: true,
          errorContainer: '#error-container',
      });

      // render the form
      ycPay.renderCreditCardForm();

      // start the payment on button click
      document.getElementById('pay').addEventListener('click', function() {
        // execute the payment
        ycPay.pay(tokenId)
          .then(successCallback)
          .catch(errorCallback);
      })

      function successCallback(response) {
        // your code here
      }

      function errorCallback(response) {
        // your code here
      }
    </script>
    
  

Sandbox Backend Integration

On the backend side, after installing our SDK, you need to indicate that you want to use the sandbox mode by using setIsSandboxMode static method. You can then use the following snippet in order to generate a token for a certain transaction, or view a specific transaction by providing the transaction ID, just like the live mode

Congrats, now you can use the sandbox mode of YouCan Pay!

Code
    
      composer require youcanpay/payment-sdk

    // setting the sandbox mode
    YouCanPay::setIsSandboxMode(true)

    $youCanPay = YouCanPay::instance()->useKeys('my-sandbox-private-key', 'my-sandbox-public-key');

    // generate a token for a new payment
    $token = $youCanPay->token->create("order-id", "2000", "USD", "123.123.123.123");
    var_dump($token->getToken(), $token->getRedirectURL());

    // get details of a transaction
    $transaction = $youCanPay->transaction->get('transaction-id');
    var_dump($transaction->getAmount(), $transaction->getCurrency());
    </script>