Express Checkout

In order to use express checkout, the customer does not need to be logged in to or even already have an account in that shop. It’s just fill the basket, approve the payment with the 3rd party and all necessary information to place the order is provided to the shop.

"Client (PWA)" -> "Base GraphQL API": token query (JWT for anonymous or existing user)
"Client (PWA)" -> "Storefront GraphQL API": basketCreate mutation
"Client (PWA)" <- "Storefront GraphQL API": Basket datatype or error
"Client (PWA)" -> "Storefront GraphQL API": basketAddProduct mutation
"Client (PWA)" <- "Storefront GraphQL API": Basket datatype or error
"Client (PWA)" -> "3rd party module GraphQL API": 3rdPartyExpressApprovalProcess query
"Client (PWA)" <- "3rd party module GraphQL API": 3rdPartyCommunicationInformation or error
"Client (PWA)" -> "Storefront GraphQL API": placeOrder mutation
"Client (PWA)" <- "Storefront GraphQL API": Order datatype or error

As we have no session in the GraphQL storefront to help us identify a possibly anonymous user, we added the possibility to the GraphQL-Base module to provide a - what we call - anonymous token. If no username and/or password is present in the token query, the user gets a random userid which is only present in the token but not in the shop’s oxuser table. Users with such an anonymous token will be put in a virtual oxidanonymous group and the rights to manipulate a basket can be given to that virtual user group.

Important

If such an anonymous user loses their JWT token, they will lose the basket.

Request for an anonymous token:

query {
    token
}

Please refer to Authorization for more details.

Provide permissions

In the GraphQL Storefront module only special shop user groups are given the rights to prepare a basket and place an order. A 3rd party payment module can have its own PermissionProvider, opening up the rights of existing queries to additional user groups or adding own rights for module specific queries and mutations.

<?php

declare(strict_types=1);

namespace Full\Qualified\Namespace\Shared\Service;

use OxidEsales\GraphQL\Base\Framework\PermissionProviderInterface;

final class PermissionProvider implements PermissionProviderInterface
{
    public function getPermissions(): array
    {
        return [
            'oxidcustomer' => [
                '3RDPARTY_EXPRESS_APPROVAL'
            ],
            'oxidnotyetordered' => [
                '3RDPARTY_EXPRESS_APPROVAL'
            ],
            'oxidanonymous' => [
                'CREATE_BASKET',
                'ADD_PRODUCT_TO_BASKET',
                'REMOVE_BASKET_PRODUCT',
                'ADD_VOUCHER',
                'REMOVE_VOUCHER',
                'PLACE_ORDER',
                '3RDPARTY_EXPRESS_APPROVAL'
            ],
        ];
    }
}

Place the (express checkout) order

Of course, a 3rd party payment module could come with its completely own implementation of checkout workflow. Here we will explain how to hook into the already existing Storefront placeOrder mutation.

At the point where the express checkout customer starts the placeOrder mutation, all information needs to be available to successfully finish the checkout. During the 3rdPartyExpressApprovalProcess call, 3rd party module specific information should be stored in some suitable place (additional fields for oxuserbaskets table in case of PayPal). Keep in mind that there’s no session.

The placeOrder mutation gets called as usual, the user is identified by his JWT token and we need the information, for which basket the order will be placed.

mutation {
     placeOrder(
         basketId:"bab15f075f10f62937d178866e4f791b"
     ) {
         id
         orderNumber
     }
 }

Additional logic will have to be hooked in right before the order gets finalized. For that purpose the BeforePlaceOrder event is dispatched right at the start of the placeOrder call. Please refer to Events - BeforePlaceOrder for details. In the case of the PayPal Express Checkout, the PayPal module is subscribed to this event. The PayPal module will use the earlier stored additional fields from oxuserbaskets table together with information it will fetch from the PayPal API, to prepare the basket with delivery method and eventual delivery address. The user is either matched to an existing account or a new user account gets created in the shop. When the event handling is done, all has to be ready for the order to be finalized.

Please check Third Party Payments - Best Practices for further hints.