В словесной игре, размещенной как приложение Canvas на Facebook, я хотел бы продавать расходуемый «VIP-статус на 1 год», дающий игрокам временный доступ к определенным областям в игре — с помощью Платежи Facebook Lite (без сервера).
Мой код JavaScript отображает Диалог оплаты, а затем передает signed_request в мой PHP-скрипт -
Код JavaScript в моем приложении Canvas:
function buyVip() {
var obj = {
method: "pay",
action: "purchaseiap",
product_id: "test1"
};
FB.ui(obj, function(data) {
$.post("/payment-lite.php",
{ signed_request: data.signed_request })
.done(function(data) {
location.reload();
});
});
}
Мой PHP-скрипт /payment-lite.php:
const APP_SECRET = 'XXXXXXX';
$request = parse_signed_request($_POST['signed_request'], APP_SECRET);
error_log(print_r($request, TRUE));
// TODO validate $request and set the user VIP status in the game database
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), TRUE);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return NULL;
}
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = TRUE);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return NULL;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
В приложении Панель управления -> Веб-платежи я добавил тестового пользователя и тестовый продукт с "Идентификатором продукта" test1
и ценой 0,01 евро:
Наконец, я вхожу в систему как тестовый пользователь и нажимаю кнопку в приложении, вызывающую метод buyVip
, в результате чего появляется диалоговое окно оплаты:
Затем в журналах сервера я вижу, что скрипт payment.php
вызывается успешно:
[30-Jul-2017 14:34:20 Europe/Berlin] Array
(
[algorithm] => HMAC-SHA256
[amount] => 0.01
[app_id] => 376218039240910
[currency] => EUR
[issued_at] => 1501418059
[payment_id] => 1084810821649513
[product_id] => test1
[purchase_time] => 1501418057
[purchase_token] => 498440660497153
[quantity] => 1
[status] => completed
)
Однако, когда я пытаюсь выполнить ту же процедуру позже, появляется Диалоговое окно оплаты, но затем происходит сбой после нажатия кнопки Купить с ошибкой
Возникла проблема с обработкой вашего платежа: Извините, но у нас возникли проблемы с обработкой вашего платежа. Плата за эту транзакцию не взимается. Пожалуйста, попробуйте еще раз.
И в консоли браузера я вижу код ошибки 1383001 Unknown:
{error_code: 1383001, error_message: "При обработке вашего платежа возникла проблема: извините… за эту транзакцию взимается плата. Повторите попытку."}
Что это значит, пожалуйста, почему первые запросы на покупку выполняются, а последующие терпят неудачу?
В своем приложении я конечно же собираюсь скрыть кнопку "купить вип статус" на год после удачной покупки, но все же хотелось бы знать, что тут происходит.
Также в будущем я хотел бы продавать расходные виртуальные товары, такие как «монеты», в своей игре, и тогда несколько покупок должны быть успешными.
ОБНОВЛЕНИЕ:
Я попытался использовать покупку, добавив следующий код в свой payment.php
( используя APP_ID|APP_SECRET вместо необходимого токена доступа пользователя):
$post = [
'access_token' => APP_ID . '|' . APP_SECRET,
];
$ch = curl_init('https://graph.facebook.com/498440660497153/consume');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($ch);
curl_close($ch);
error_log(print_r($response, TRUE));
Но, к сожалению, получить ошибку:
{"error":{"message":"Неподдерживаемый почтовый запрос. Объект с идентификатором '498440660497153' не существует, не может быть загружен из-за отсутствия разрешений или не поддерживает эту операцию. Пожалуйста, прочтите документацию Graph API по адресу https:/ /developers.facebook.com/docs/graph-api","type":"GraphMethodException","code":100,"fbtrace_id":"HDusTBubydJ"}}