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

Пример приложения

Код приложения, реализующего игровые платежи доступен на 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);
}

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

При закрытии окна платежа игре будет сообщен результат его проведения. Формат сообщения зависит от способа открытия вашей игры.

Приложение открывается в iframe

Если приложение открывается в iframe, то при закрытии окна платежа вашей игре будет послан postMessage, у которого в поле data будет указан результат проведения платежа:

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

Окно с платежом будет автоматически закрыто независимо от того, каким способом оно было открыто.

Приложение открывается как отдельная страница

Если приложение открывается как отдельная страница, то при закрытии окна платежа будет произведен редирект на странице вашей игры. В URL запроса будет передан результат проведения платежа в виде дополнительного GET-параметра 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");
    }