yandex money api редиректы

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Ответить
louisvuitton
Сообщения: 182
Зарегистрирован: 2014.02.16, 03:09

yandex money api редиректы

Сообщение louisvuitton » 2018.08.08, 03:15

Здравствуйте,
Делаю платежи 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) Это нормально пердевать сумму в куки? ее никто не сможет подменить между редиректами, чтобы у меня сохранилось не то значение которое было снято с карты?

Ответить