проверка api полосы для существующей карты

Я уверен, что мне здесь не хватает чего-то очевидного, но я не могу понять, как проверить наличие существующей карты у клиента.

Я использую api stripe connect в приложении laravel для управления платежами от имени других, и основной процесс выглядит следующим образом:

  • полоса token создается через stripe.js и отправляется вместе с формой оплаты
  • если клиент существует в локальной базе данных, я беру его stripe_id, в противном случае создается новый клиент с использованием токена в качестве источника / карты
  • затем создается charge с использованием полученного или нового клиента stripe_id

В настоящее время, если клиент возвращается и использует другую карту, поскольку плата включает только клиента, а не источник, она будет снята с его карты по умолчанию независимо от того.

Что бы я хотел сделать:

  • создать полосу token
  • проверьте customer на локальную базу данных и т. д.
  • сверить card отпечаток пальца с карточкой клиента
  • при необходимости создайте новый card в записи клиента
  • создать платеж с использованием идентификаторов customer и card

Проще говоря: я не вижу, где в процессе создается постоянный card_id; и те, что используются в ответе stripe.js, и когда они созданы на панели инструментов полосы, кажутся уникальными, что означает, что каждое начисление создает совершенно новый объект карты в полосе.

Я знаю, что могу получить список карт, хранящихся в учетной записи клиента, но где мне взять начальный card_id для поиска?

Я видел здесь вопрос, касающийся этого - Могу ли я проверить, существует ли уже разделенная карта, прежде чем создавать новую? - но я не знаю Ruby, поэтому не могу разобраться в этом .

РЕДАКТИРОВАТЬ:

Более простая версия - есть ли способ получить fingerprint, как описано в документах по полосе здесь - https://stripe.com/docs/api/php#card_object - без предварительного создания объекта карты?


person taekni    schedule 23.03.2015    source источник


Ответы (2)


Идея здесь состоит в том, чтобы использовать fingerprint в объекте Card или Token, а не сам идентификатор, поскольку они будут другими, если вы добавите одну и ту же карту несколько раз.

Когда вы получаете новый токен карты, вы можете получить его с помощью API Получить токен и найти fingerprint в хэше card.

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

ПРИМЕЧАНИЕ. убедитесь, что вы используете секретные ключи для получения этой информации. в противном случае, если вы используете публикуемый ключ, вы можете не получить значение отпечатка пальца.

person koopajah    schedule 24.03.2015
comment
Ваша идея идеальна, но вы не знаете, почему полоса не возвращает fingerprint в Retrieve Token API. Если есть идеи, почему полоса не возвращается, поделитесь, пожалуйста. - person Mahesh Agrawal; 12.10.2016
comment
@ M.K. Stripe определенно возвращает этот отпечаток на этом API. Единственный случай, когда вы не видите отпечаток пальца, - это если вы используете для этого свой публикуемый ключ, и он явно задокументирован здесь: stripe.com/docs/upgrades#2014-10-07 - person koopajah; 12.10.2016
comment
ох .... я понял .. теперь я могу получить отпечаток пальца. большое спасибо. редактирую ваш ответ с помощью этой заметки. так что никого не перепутаешь. еще раз большое спасибо. - person Mahesh Agrawal; 12.10.2016
comment
Имейте в виду, что если вы сделаете это, и Клиент попытается отправить ту же карту, но с другим сроком действия, они не будут допущены. - person jonathancardoso; 14.03.2017
comment
@JCM и правильно, их нельзя допускать. Если срок действия карты истек, вы всегда получаете новую карту с новым номером карты и сроком действия. - person user3574492; 14.06.2018
comment
@ user3574492 вы не всегда получаете новую карту, возможно, даже можно с уверенностью сказать, что большинство эмитентов собираются выдать вам карту с тем же номером, но отличается только трехзначный код - person jonathancardoso; 16.06.2018
comment
@JCM Каждый эмитент должен предоставить вам новую карту с новым номером карты, когда срок ее действия истечет. номер счета остается прежним, но длинный номер карты всегда отличается, как и cvc для обновленных карт. - person user3574492; 16.06.2018
comment
@ user3574492 Вы ошибаетесь. Я только что получил по почте новую кредитную карту VISA (когда срок действия моей старой истек) с тем же номером, новым сроком действия и новым CVC. - person xinthose; 26.09.2019
comment
Законно ли (в США) хранить отпечатки пальцев карты в базе данных приложения? - person yaswant singh; 04.10.2019
comment
@yaswantsingh Да, и Stripe явно упоминает, что вы должны хранить это значение в своей базе данных вместе с customer.id, paymentMethod.id, last4, exp_month, exp_year, brand (as in "Visa", "Mastercard" etc.), чтобы поддерживать хорошую производительность сайта и сокращать количество обращений к Stripe API. - person A Friend; 04.09.2020

Я создал для этого функцию:

  • $customer - полосовой объект клиента
  • $stripe_account - это либо идентификатор полосы вашей учетной записи, либо идентификатор полосы подключенной учетной записи.
  • $token происходит из элементов stripe.js
  • $check_exp позволяет вам решить, хотите ли вы также проверить срок действия карты, потому что отпечаток пальца не меняется, если номер карты тот же
  • полоса PHP API 7.0.0

    function check_duplicate_card($customer, $stripe_account, $token, $check_exp) {
    $loc = "check_duplicate_card >> ";
    $debug = true;
    
    if ($debug) {
        // see here for an explanation for logging: http://php.net/set_error_handler >> Examples
        trigger_error("$loc started", E_USER_NOTICE);
    }
    
    try
    {
        // get token data
        $response = \Stripe\Token::retrieve(
            $token,
            ["stripe_account" => $stripe_account]
        );
        $token_fingerprint = $response->card->fingerprint;
        $token_exp_month = $response->card->exp_month;
        $token_exp_year = $response->card->exp_year;
        if ($debug) {
            trigger_error("$loc token_fingerprint = $token_fingerprint; token_exp_month = $token_exp_month; token_exp_year = $token_exp_year", E_USER_NOTICE);
        }
    
        // check for duplicate source
        if ($debug) {
            trigger_error("$loc customer sources = " . json_encode($customer->sources), E_USER_NOTICE);
        }
        $duplicate_found = false;
        foreach ($customer->sources->data as &$value) {
            // get data
            $fingerprint = $value->fingerprint;
            $exp_month = $value->exp_month;
            $exp_year = $value->exp_year;
    
            if ($fingerprint == $token_fingerprint) {
                if ($check_exp) {
                    if (($exp_month == $token_exp_month) && ($exp_year == $token_exp_year)) {
                        $duplicate_found = true;
                        break;
                    }
                } else {
                    $duplicate_found = true;
                    break;    
                }
            }
        }
        if ($debug) {
            trigger_error("$loc duplicate_found = " . json_encode($duplicate_found), E_USER_NOTICE);
        }
    } catch (Exception $e) {
        if ($e instanceof \Stripe\Exception\ApiErrorException) {
            $return_array = [
                "status" => $e->getHttpStatus(),
                "type" => $e->getError()->type,
                "code" => $e->getError()->code,
                "param" => $e->getError()->param,
                "message" => $e->getError()->message,
            ];
            $return_str = json_encode($return_array);
            trigger_error("$loc $return_str", E_USER_WARNING);
            http_response_code($e->getHttpStatus());
            echo $return_str;
        } else {
            $return_array = [
                "message" => $e->getMessage(),
            ];
            $return_str = json_encode($return_array);
            trigger_error("$loc $return_str", E_USER_ERROR);
            http_response_code(500); // Internal Server Error
            echo $return_str;
        }
    }
    
    if ($debug) {
        trigger_error("$loc ended", E_USER_NOTICE);
    }
    
    return $duplicate_found;
    }
    
person xinthose    schedule 26.09.2019