Пример проведения мобильного платежа

Код приложения, реализующего игровые платежи доступен на GitHub
Работу тестового приложения можно проверить по адресу https://m.ok.ru/game/okPaymentExample

Процесс проведения платежа

Проведение игрового платежа состоит из следующих этапов:

  1. Внутри приложения вызывается метод показа игрового платежа:
    • в случае, если игра запущена в Android-приложении Одноклассников, рекомендуем использовать метод OKSDK.Payment.show;
    • в случае, если игра запущена в мобильном Chrome, рекомендуем использовать метод OKSDK.Payment.showInFrame;
    • в иных случаях нет предпочтений / рекомендаций и можно использовать любой из указанных выше методов.
  2. Платеж либо происходит сразу, либо пользователю даётся возможность отменить платеж / подтвердить платеж.
  3. В случае подтверждения платежа на ваш callback-сервис, указанный в настройках приложения отправляется GET-запрос с параметрами платежа. Возможные значения параметров и также формат ответа описаны в документации по методу callbacks.payment.
  4. При любом исходе пользователь закрывает игровой платеж и в том же окне / фрейме производится перенаправление пользователя на страницу игры. При открытии игры в custom_args передается информация о платеже:
    • в случае успешного завершения платежа - payment=ok;
    • в случае отмены / ошибки платежа - payment=cancel.
  5. Игра обрабатывает переданный параметр payment и закрывает окно платежа, сообщая пользователю о результате проведения платежа.

Показ окна платежа

Для работы платежных методов OKSDK предварительно надо инициализировать SDK с помощью метода OKSDK.init.

Окно платежа можно показывать двумя способами:

  • в отдельном всплывающем окне с помощью метода OKSDK.Payment.show;
  • во встроенном на страницу игры фрейме с помощью метода OKSDK.Payment.showInFrame.

Ввиду особенностей работы платежной системы Одноклассников, а также мобильных браузеров, рекомендуется для мобильного браузера Chrome показывать платеж исключительно в фрейме.

Для платежей в игре, открытой в Android-приложении Одноклассников следует открывать платежи в отдельном окне.

Чтобы определить, запущена ли игра в Android-приложении, можно воспользоваться методом OKSDK.Util.isLaunchedFromOKApp.

Валидация платежного callback’а

При подтверждении платежа пользователем перед тем как завершить платеж на ваш платежный callback-сервис, адрес которого вы указали в настройках приложения, придет GET-запрос с параметрами платежа.

Для избежания случаев поддельных платежей рекомендуем валидировать все пришедшие на ваш callback-сервис запросы.

Подробная информация о параметрах запроса, приходящего на callback-сервис, вы можете ознакомиться здесь: callbacks.payment.

Простейший пример валидации платежа представлен ниже:

// функция рассчитывает подпись для пришедшего запроса
// подробнее про алгоритм расчета подписи можно посмотреть в документации (https://apiok.ru/dev/methods/)
function calcSignature($request) {
    $tmp = $request;
    unset($tmp["sig"]);
    ksort($tmp);
    $resstr = "";
    foreach($tmp as $key=>$value) {
        $resstr = $resstr.$key."=".$value;
    }
    // сюда необходимо подставить свой секретный ключ
    $resstr = $resstr.self::APP_SECRET_KEY;
    return md5($resstr);
}

Обработка результатов проведения платежа

При отмене или успешном завершении платежа пользователь будет перенаправлен на страницу игры. При этом в URL игре будет передан параметр custom_args со значением:

  • payment=cancel - при отмене / ошибке проведения платежа;
  • payment=ok - при успешном проведении платежа.

При любом способе открытия игрового платежа приложение может обработать этот запрос. При обработке платежа рекомендуется:

  • оповещать пользователя о результатах проведения платежа;
  • закрывать страницу игры, открытую в результате проведения платежа.

Для этого в код страницы игры можно встроить код, который при открытии будет проверять наличие переданного в URL параметра payment.

Например, это можно сделать следующим образом:

    document.addEventListener('DOMContentLoaded', function () {
        var config = {
            app_id: 0,      // <-- insert APP ID here
            app_key: ''     // <-- insert APP PUBLIC KEY here
        };

        OKSDK.init(config, function () {
            // onSuccessInit
        }, function (error) {
            alert('OKSDK error' + OKSDK.Util.toString(error));
        });

        // проверка наличия параметра payment
        let args = OKSDK.Util.getRequestParameters(window.location.search);
        if (args['custom_args'] && (args['custom_args'].search("payment") == 0)) {
            // When payment is finished the application is being re-launched with
            // custom_args containing "payment=ok" or "payment=cancel".
            //
            // We've detected that the launch is a payment callback, and since we opened a new window
            // for payment processing, we should send the message to our original game window
            // and close the current window.
            //
            let paymentResult = decodeURIComponent(args['custom_args']).split('=');

            // Обработка платежа, открытого в фрейме
            if (window.parent) {
                    window.parent.postMessage(JSON.stringify({
                        type: 'payment',
                        result: paymentResult
                    }), "*");
                OKSDK.Payment.closePaymentFrame("paymentFrame");
            }

            // Обработка платежа, открытого в отдельном окне
            if (window.opener) {
                    // Post a message {type:"payment",result:"..."}
                    window.opener.postMessage(JSON.stringify({
                        type: 'payment',
                        result: paymentResult
                    }), "*");
                    window.close();
                    return;
            }
        }
    });

Платеж в отдельном окне

При открытии платежа в отдельном окне вы можете:

  • отослать в родительское окно сообщение (postMessage);
  • закрыть дочернее окно игры;
  • в родительском окне обработать пришедшее сообщение и показать пользователю информацию о проведении платежа. Например, сразу же начислить ему игровую валюту.

Пример кода, обрабатывающего эту ситуацию представлен ниже:

    if (window.opener) {
            // Post a message {type:"payment",result:"..."}
            window.opener.postMessage(JSON.stringify({
                type: 'payment',
                result: paymentResult
            }), "*");
            window.close();
            return;
    }

Платеж в фрейме

При открытии платежа в фрейме вы можете:

  • отослать в родительский элемент фрейма сообщение (postMessage);
  • закрыть контейнер, содержащий фрейм с игрой с помощью метода OKSDK.Payment.closePaymentFrame;
  • в исходном окне игры обработать пришедшее сообщение и показать пользователю информацию о проведении платежа. Например, сразу же начислить ему игровую валюту.

Пример кода, обрабатывающего эту ситуацию представлен ниже:

    if (window.parent) {
            window.parent.postMessage(JSON.stringify({
                type: 'payment',
                result: paymentResult
            }), "*");
        OKSDK.Payment.closePaymentFrame("paymentFrame");
    }