developer

Workflow to create a checkout against API v3 with PHP and Guzzle

Preparation

Install Guzzle

First of all you need to install Guzzle. Please follow the steps here You can also use HTTP-Client or plain cURL if you want to reduce footprint of your implementation.

Create API-Token

We will use our all new RESTfull API. To authorize against this API, one have to create an API-Access-Token. You will need settings section in plenigo-Backend and at least the right to write Settings, to create a new Access-Token.

Examples for external User-Management

At the moment we only provide examples for external customer management.

Initialize Guzzle

$client = new GuzzleHttp\Client(['base_uri' => 'https://api.plenigo.com/api/v3.0/']);

POST the Customer

We tried to keep the examples as simple as possible. You can pimp the guzzle client as much as you want .

$client = new GuzzleHttp\Client(['base_uri' => 'https://api.plenigo.com/api/v3.0/']);
$user = [
    'customerId' => "4711", // User-ID in external system
    'email' => "{$emailAdress}", // E-Mail address of your customer
    'language' => 'de',
  ];

$response = $client->request('POST', 'customers', [
    // here you will need to work with the Api-Access token from plenigo backend
    'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
    // the payload, we'll send
    'json' => $user
]);

$customer = json_decode($response->getBody()->getContents());

This will return the created user or the already existing user. It will not recreate it.

Create Checkout-Code

After having a customer we need to create a checkout token:

// @see https://stackoverflow.com/a/55790/2336470
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

$payload = [
    "debugMode" => true, // enable debugging in checkout (please turn it off in prod environment)
    "customerIpAddress" => $ip,
    "customerId" => $customer->customerId,
    "items" => [
        [
            "plenigoOfferId" => "O_6E487EBURRY35FOD0J",
            "quantity" => 1,
        ],
    ],
]);

$response = json_decode($client->request('POST', '/checkout/preparePurchase', [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

Create the Checkout

In your HTML-Code you will need to add the plenigo Javascript.

<!-- plenigo Javascript SDK will inject the Checkout into this div -->
<div id="plenigoCheckout"></div>

<script>
    // if your're working against the staging system, you have to extend the endpoint
    var plenigo = plenigo || {};
    plenigo.configuration = plenigo.configuration || {};
    plenigo.baseCheckoutURI = "https://checkout.plenigo-stage.com";
</script>

<script src="https://static.plenigo.com/static_resources/javascript/{YourCompanyId}/plenigo_sdk.min.js"
        type="text/javascript" data-disable-metered="true" data-oauth2-access-code="oauth2Test"></script>

<script>

  new plenigo.Checkout("<?php echo $response->purchaseId;  ?>", {elementId: "plenigoCheckout"}).start();

  // this will be triggered, if Checkout is finished successfully
  document.addEventListener("plenigo.PurchaseSuccess", function (e) {
    // debugging Code:
    console.info("Event is: ", e);
    console.info("Custom data is: ", e.detail);
    location.href = location.pathname + "?" + e.orderId;
    // please take care by using orderId in your scripts. It can be -1, if customer tries to buy a product multiple times
  });

  // if you enabled WebAnalytics, then you will recieve some additional information during the checkout 
  document.addEventListener("plenigo.WebAnalyticsLoad", function (e) {
    // debugging Code:
    console.group("ANALYTICS");
    console.info("Event is: ", e);
    console.info("Custom data is: ", e.detail);
    console.groupEnd();
  });

</script>

Since plenigo checkout will prevent customers from buying same product multiple times, orderId will be -1, if product is already bought.

Purchase a single product and overwrite it with custom data

Some may have hundreds of identical products. Lets say, you are publishing one ePaper a day. And you want to be able to sell each of them. Then you should not create a new product every day - just reuse an old one. Create one product in the plenigo backend for all of your pdf-files, and sell it this way:

// @see https://stackoverflow.com/a/55790/2336470
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

$payload = [
    "debugMode" => true, // enable debugging in checkout (please turn it off in prod environment)
    "customerIpAddress" => $ip,
    "customerId" => $customer->customerId,
    "items" => [
        [
            "plenigoOfferId" => "O_6E487EBURRY35FOD0J", // offerId of your all pdf product
            "quantity" => 1,
            "title" => "my daily ePaper issue: 2020-04-04",
            "products" => [
               [
                   "plenigoProductId" => "P_GZUZGJHGJHGGJ", // productID of the underlying product
                   "productId" => "ePaper-2020-04-04", // unique ID to make you able to differentiate between singular issues
                   "price" => 5, // you can overwrite price (only if you want to)
                   "title" => "my daily ePaper issue: 2020-04-04", // we will provide multi product offers
                   "accessRightUniqueId" => "ePaper-2020-04-04", // to be able to give access to one specific issue, you need to set specific access right
               ]
           ]

        ],
    ],
]);

$response = json_decode($client->request('POST', '/checkout/preparePurchase', [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

Purchase a shopping cart

You can sell multiple offers in one checkout by passing multiple items in the purchase payload. A different approach would be, configure shopping carts to sell multiple offers.

You have to configure those shopping carts in the plenigo merchant backend. The code to sell them would be the following:

// @see https://stackoverflow.com/a/55790/2336470
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

$payload = [
    "debugMode" => true, // enable debugging in checkout (please turn it off in prod environment)
    "customerIpAddress" => $ip,
    "customerId" => $customer->customerId,
    // there should not be any items attribute here
    "basketId" => "SC_UKKJH8KJHKJ",
]);

$response = json_decode($client->request('POST', '/checkout/preparePurchase', [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

Check Access

If you are selling products, you want to give your customers access to your digital goods. With plenigo you simply use the method hasAccess

try {

    $response = json_decode($client->request('GET', "accessRights/{$customer->customerId}/hasAccess?accessRightUniqueIds=ePaper-2020-04-04", [
        'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw']
    ])->getBody()->getContents()));

   $access = $response->accessGranted; // here we get the access status

} catch(\GuzzleHttp\Exception\ClientException $e) {
    // with external user managment we can't guarantee for an existing plenigo user. in these case you have to catch a GuzzleHttp\Exception\ClientException - this user should not get any access
    $access = false;
}

Guzzle loves to throw Exceptions. In case of a missing user plenigo will return a 404 StatusCode - guzzle will turn this into a GuzzleHttp\Exception\ClientException.

Work with Sessions, use plenigo SSO

If plenigo is used as a SSO you have to deal with sessions. You can use the session, to start a Checkout, to check users access rights or start selfservice process.

Create a transfer token

To open plenigo selfservice you need to have a transfer token:

    
    // @see https://api.plenigo-stage.com/#operation/createTransferToken
    // $session should be the plenigo session token
    $payload = ['customerSession' => $session];
    try {        
        $response = json_decode($client->request('POST', '/sessions/transferToken', [
          'headers' => [
            'X-plenigo-token' =>                        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

    $transferToken = $response->transferToken;
    
   } catch (\GuzzleHttp\Exception\ClientException $exception) {
        // handle errors
    }

use token to start selfservice

<div id="plenigoCheckout"></div>
    <script src="https://static.plenigo-stage.com/static_resources/javascript/<?php echo $companyId; ?>/plenigo_sdk.min.js"
            type="text/javascript" data-disable-metered="true" data-lang="de" data-disable-redirect="true"></script>

    <script>
        new plenigo.Snippets("<?php echo $transferToken; ?>", {elementId: "plenigoCheckout"}).start();
    </script>

Start a checkout with plenigo session

// @see https://stackoverflow.com/a/55790/2336470
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

$payload = [
    "debugMode" => true, // enable debugging in checkout (please turn it off in prod environment)
    "customerIpAddress" => $ip,
// $session is you plenigo session token
// @see https://api.plenigo-stage.com/#operation/preparePurchase
    "customerSession" => $session,
    "items" => [
        [
            "plenigoOfferId" => "O_6E487EBURRY35FOD0J",
            "quantity" => 1,
        ],
    ],
]);

$response = json_decode($client->request('POST', '/checkout/preparePurchase', [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

Check access with plenigo session

// https://customer-api.plenigo-test.com/#operation/checkAccessOfCustomer
$response = json_decode($client->request('GET', 'https://customer-api.plenigo-stage.com/api/v1.0/accessRights/hasAccess', [
      'headers' => ['X-plenigo-customer-session' => $session],
])->getBody()->getContents());

if ($response->accessGranted) {
// show content
}

plenigo voucher process

Vouchers enable you to sell products you don’t want to show on your website. Vouchers are always connected to a plenigo product. So voucher process is thought like a normal checkout: it generates an order.

Validate a voucher code

You can split voucher process into the validation and redemption part. Validating a voucher code will return status of the code and the plenigo offer it will be redeemed into:

// @see https://api.plenigo-stage.com/#operation/validateVoucherCode

$response = json_decode($client->request('GET', "/vouchers/{$voucherCode}/validate", [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => null
])->getBody()->getContents());

Redeem into a free offer

If plenigo offer is a free product, you can redeem a voucher simply by calling https://api.plenigo-stage.com/#operation/voucherPurchase.

// @see https://stackoverflow.com/a/55790/2336470
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

// @see https://api.plenigo-stage.com/#operation/voucherPurchase

$payload = [
    'customerId' => '123',
    'customerIpAddress' => $ip,
    'voucherCode' => "1234-5678-1234"
];

$response = json_decode($client->request('POST', "/checkout/buyWithVoucher", [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

Redeem into a not free offer

If offer is not free or you are not sure, you can use the checkout process to redeem the voucher code. Checkout process will run with a free offer too.

// @see https://stackoverflow.com/a/55790/2336470
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
}

// @see https://api.plenigo-stage.com/#operation/preparePurchase

$payload = [
    "debugMode" => true, // enable debugging in checkout (please turn it off in prod environment)
    "customerIpAddress" => $ip,
    "customerId" => $customer->customerId,
    "voucherCode" => "1234-5678-1234"
]);

$response = json_decode($client->request('POST', '/checkout/preparePurchase', [
      'headers' => ['X-plenigo-token' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aGVzZSI6ImFyZSIsInBsZW5pZ28iOiJ0ZXN0IiwiZGF0YSI6ImRvIiwibm90IjoiY29uc3VtZSJ9.xnFAQQbHEFLisgeU2YqWsIfpCgEbmh_Hy59Ja0Ztxyw'],
      'json' => $payload
])->getBody()->getContents());

This will generate a purchaseToken. In the next step you have to start the checkout.