Делаю платежи c банковских карт с помощью api яндекс денег.
Возникли несколько вопросов. Посмотрите пожалуйса кто может.
У яндекса есть тестовое приложение, мне нужна часть где пользователи могут вносить платежи с карты на кошелек ЯД, поэтому делал по подобиям методов
$app->post("/wallet/process-external/" ... ) {...}
$app->get("/wallet/external-success/" ... ) {...}
Делаю так
Код: Выделить всё
// в этот метод приходит сумма из формы заполненной пользователем
public function actionPaycard() {
$cookie_expired = time() + (20 * 60);
$walletTo = $this->getWalletTo();
$sum = Yii::$app->request->post('sumcard');
// получаю instace_id
$instance_id_json = ExternalPayment::getInstanceId('ID_YM');
// добавляю instance_id в куки
Yii::$app->response->cookies->add(new \yii\web\Cookie([
'name' => 'instance_id',
'value' => $instance_id_json->instance_id,
'expire' => $cookie_expired,
]));
$instance_id = $instance_id_json->instance_id;
$api = new ExternalPayment($instance_id);
// запрос процесса платежа
$request_result = $api->request(array(
"pattern_id" => "p2p",
"to" => $walletTo,
"amount_due" => $sum,
));
if($request_result->status != "success") {
Yii::$app->getSession()->setFlash('error', [
'message' => 'Ошибка на стороне системы платежей',
]);
return $this->redirect('/');
}
Yii::$app->response->cookies->add(new \yii\web\Cookie([
'name' => 'request_id',
'value' => $request_result->request_id,
'expire' => $cookie_expired,
]));
// получаю результат платежа и url для перенаправления на дальнейшие действия в зависимости от того прошел платеж или нет
$process_result = $api->process(array(
"request_id" => $request_result->request_id,
"ext_auth_success_uri" => Url::to('card-success', true),
"ext_auth_fail_uri" => Url::to('card-fail', true),
));
Yii::$app->response->cookies->add(new \yii\web\Cookie([
'name' => 'result/request',
'value' => json_encode($request_result),
'expire' => $cookie_expired,
]));
// перенаправляю на полученый url
$url = sprintf("%s?%s", $process_result->acs_uri,
http_build_query($process_result->acs_params));
return $this->redirect($url);
}
// если в предыдущем методе платеж прошел, перенаправление идет сюда
public function actionCardSuccess() {
//из кук берутся параметры платежа
$request_id = Yii::$app->request->cookies->getValue('request_id');
$instance_id = Yii::$app->request->cookies->getValue('instance_id');
if(is_null($request_id) || is_null($instance_id)) {
Yii::$app->getSession()->setFlash('error', [
'message' => 'Ошишибка системы платежей (cookie expired)',
]);
return $this->redirect('/');
}
// еще раз проверяется все ли нормально прошли ли деньги по этому платежу (второй раз не снимутся)
$api = new ExternalPayment($instance_id);
do {
$result = $api->process(array(
"request_id" => $request_id,
"ext_auth_success_uri" => Url::to('card-success', true),
"ext_auth_fail_uri" => Url::to('card-fail', true),
));
if($result->status == "in_progress") {
sleep(1);
}
} while ($result->status == "in_progress");
// если все прошло мне надо сохранить у себя платеж пользоватля и вывести что все ок (почему то бывает, что в этот if попадаю более одного раза! см вопрос 1 )
if($result->status == "success") {
$req = json_decode(Yii::$app->request->cookies->getValue("result/request"));
$sum = $req->contract_amount - $req->fees->service; // получаю сумму из куки запроса платежа (снятые деньги - комиссия), т.к. она не передается в ответе от банка $api->process(...) а только в $api->request(...)
$user = Yii::$app->user->identity;
if($user->addPay($sum, PAY_METHOD_CARD)) {
Yii::$app->getSession()->setFlash('success', [
'message' => 'Платеж успешно выполнен на сумму <strong>' . $sum . '</strong> руб.',
]);
$this->removeCardCookies();
return $this->redirect('/');
}
}
// если после всех попыток платеж будет "refused"
else {
$this->removeCardCookies();
Yii::$app->getSession()->setFlash('error', [
'message' => 'Ошишибка на стороне системы платежей (process)',
]);
return $this->redirect('/');
}
}
public function actionCardFail() {
Yii::$app->getSession()->setFlash('error', [
'message' => 'Ошишибка на стороне системы платежей (redirect failed)',
]);
return $this->redirect('/');
}
1) главный - Почему случается так, что иногда после всех редиректов, информация о платеже сохраняется (метод $user->addPay(..)) дважды (такое происходит не всегда, вообще непонятно в каких случаях воспроизводится баг и почему) Как этого избежать?
2) В какой момент удалять куки, чтобы не было ошибок и нельзя было повторить actionCardSuccess с этими же куками сохранив платеж еще раз?
2) Это нормально пердевать сумму в куки? ее никто не сможет подменить между редиректами, чтобы у меня сохранилось не то значение которое было снято с карты?