Stripe api проверка существующей карты

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

Я использую API-интерфейс Stripe Connect в приложении Laravel для управления платежами от имени других, и основной процесс заключается в следующем:

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

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

Я хотел бы сделать следующее:

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

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

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

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

EDIT:

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

Ответ 1

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

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

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

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

Ответ 2

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

  • $customer является объектом клиента полосы
  • $stripe_account является либо идентификатором вашей учетной записи, либо идентификатором подключенной учетной записи
  • $token происходит от элементов stripe.js
  • $check_exp позволяет вам решить, хотите ли вы также проверить дату истечения срока действия карты, потому что fingerprint не меняется, если номер карты совпадает
  • нашивка 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;
    }