#rest #stripe-payments
#rest #stripe-платежи
Вопрос:
Я использую Stripe API, и я хотел бы представить моему клиенту список истории их счетов-фактур вместе с соответствующими квитанциями.
Я нигде не могу найти в Stripe API (https://stripe.com/docs/api?lang=php ) это позволяет мне получить список квитанций клиента. Я чего-то не понимаю?
Комментарии:
1. Я пытаюсь добиться того же. При запросе в IRC-канале #stripe мне сказали, что нет способа получить идентификатор квитанции по электронной почте. :
Ответ №1:
Каждый счет включает charge
свойство, которое содержит идентификатор его последнего платежа. Это будет либо текущая / последняя попытка оплаты (для счетов, которые не были успешно оплачены), либо успешный платеж (для оплаченных счетов).
Это позволяет вам легко использовать данные оплаты и счета-фактуры для представления квитанции пользователю, но «квитанция» сама по себе является скорее понятием на стороне приложения; его потребности и представление зависят от приложения.
Получив данные, вы можете представить квитанцию так, как вам нравится.
В идеале я рекомендую кэшировать эти записи локально. Это почти безболезненно, если вы получаете веб-ссылки. Затем вы можете смоделировать (и выполнить поиск!) локальную запись квитанции так, чтобы она наилучшим образом соответствовала вашим потребностям, ваш клиент получит преимущество очень быстрого отображения счета, а мы все получим преимущество меньшей нагрузки на конечные точки API Stripe.
Комментарии:
1. Конечно, это хороший способ сделать это, если у вас есть несколько дней, чтобы потратить. Однако Stripe в значительной степени ориентирован на быструю и простую интеграцию, и это, безусловно, не является ни быстрым, ни простым. Учитывая, что Stripe уже предлагает квитанции по электронной почте , и вы также можете просматривать их на панели мониторинга, я думаю, разумно спросить, есть ли способ получить именно эти квитанции из API. (Я также еще не нашел способ сделать это.)
Ответ №2:
Я смог сделать это немного хакерским способом в библиотеках Java и Apache IO / Lang.
ПРИМЕЧАНИЕ — это решение на Java, но общая идея должна легко работать на любом другом языке.
Я добавил в свой pom.xml
файл следующее: —
<dependencies>
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>19.24.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
...
</dependencies>
Шаги были следующими: —
- Используйте Stripe API для возврата списка объектов начислений (ссылка https://stripe.com/docs/api/charges/list ).
- Выполните итерацию по каждому объекту начисления и обратите внимание на
receipt_url
(ссылка https://stripe.com/docs/api/charges/object ). - Загрузите страницу квитанции (HTML) в a
String
, например, с помощью IOUtils.toString - Извлеките URL-адрес загрузки квитанции (он содержит
invrc_xxx
, например https://dashboard.stripe.com/emails/receipts/invrc_NmIZClQPPEELg1J0QvNJ6sJQ/pdf ). Я использовал базовый вызов StringUtils.substringBetween для извлечения этого.
ПРИМЕЧАНИЕ: преобразование HTML-страницы в XML и извлечение ее через XPath было бы более профессиональным.
- Загрузите этот URL-адрес локально в формате PDF, используя, например, FileUtils.copyURLToFile.
Код выглядит следующим образом: —
import com.stripe.Stripe;
import com.stripe.model.Charge;
import com.stripe.model.ChargeCollection;
import com.stripe.param.ChargeListParams;
import java.io.File;
import java.net.URL;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
public class StripeReceiptDownloader {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("Missing Stripe API key");
System.exit(-1);
}
Stripe.apiKey = args[0];
File downloadFolder = new File("stripe-receipts");
// Return a list of charges and loop through each
ChargeCollection charges = Charge.list(ChargeListParams.builder().setLimit(3L).build());
for (Charge charge : charges.getData()) {
// Download HTML page from receipt_url in charge object
String receiptPageContents = IOUtils.toString(new URL(charge.getReceiptUrl()));
// Extract invcrc ID
String invrcId = StringUtils.substringBetween(receiptPageContents, "receipts/invoices", "/pdf");
String receiptPdfDownload = "https://dashboard.stripe.com/receipts/invoices" invrcId "/pdf";
String filename = invrcId ".pdf"; // you could also use fields from charge object to give better context to filename
File receiptFile = new File(downloadFolder, filename);
System.out.println("Downloading [ " receiptPdfDownload " ] to [ " receiptFile " ]");
FileUtils.copyURLToFile(new URL(receiptPdfDownload), receiptFile);
}
}
}
Это загрузит квитанции в указанную папку и выведет что-то вроде следующего: —
Downloading [ https://dashboard.stripe.com/emails/receipts/invrc_1J2lQPQvELg6sNJNmIZECPJQ/pdf ] to [ stripe-receipts1J2lQPQvELg6sNJNmIZECPJQ.pdf ]
Downloading [ https://dashboard.stripe.com/emails/receipts/invrc_1ItqEg6L62JELNmIZDMzBrY7/pdf ] to [ stripe-receipts1ItqEg6L62JELNmIZDMzBrY7.pdf ]
Downloading [ https://dashboard.stripe.com/emails/receipts/invrc_1IzmM1aJNIZ6fTEELgt07wYW/pdf ] to [ stripe-receipts1IzmM1aJNIZ6fTEELgt07wYW.pdf ]
Ответ №3:
Это действительно не было бы слишком сложно. Сначала вы получите все счета-фактуры:
https://stripe.com/docs/api?lang=php#invoice_object
https://stripe.com/docs/api?lang=php#list_customer_invoices
У каждого счета-фактуры есть свойство «customer», поэтому все, что вам нужно сделать, это выполнить поиск в них для счета-фактуры с идентификатором клиента, который соответствует вашему.
У каждого счета-фактуры есть свойство «receipt_number», так что все должно быть готово!
Комментарии:
1. к сожалению, ‘receipt_number’ ссылается на код квитанции (т.е. 2535-2928), а не на receipt_id (т.е. invrc_14t8HA2ndNH5cEQ)
2. Можете ли вы указать мне где-нибудь, где существует receipt_id? И что именно вы хотите иметь возможность представить клиенту?
3. Если вы посетите платеж на панели инструментов Stripe и нажмете «Просмотреть квитанцию», там будет постоянная ссылка на квитанцию. Я верю, что это то, что он ищет, я тоже.
4. Но, насколько я знаю, нет способа получить
invrc_XXXX
идентификатор из любого места, кроме URL-адреса.
Ответ №4:
Мне очень нравится ответ, данный colinm, и я хочу подробнее рассказать о том, почему и как, потому что я думаю, что это отличный ответ, но его можно было бы уточнить немного подробнее. Интересно, что я думаю, что все три ответа можно было бы объединить здесь, например, я бы не стал делать только одну из этих вещей, я бы сделал все три.
Я думаю, что наиболее устойчивой практикой здесь является репликация соответствующих данных локально, в вашей собственной базе данных. Это имеет несколько преимуществ, в частности:
- Производительность — Нет необходимости отправлять запрос во внешний ящик. Это значительно ускорит выполнение ваших скриптов.
- Уменьшенная нагрузка на сервер — Когда вы запрашиваете Stripe API, они обычно отправляют обратно большие объекты. У меня были возвращаемые объекты Stripe, занимающие около 40 КБ в памяти, когда мне нужно только одно значение, например целое число. Но, в зависимости от того, какой язык вы используете, простая загрузка файла для Stripe API может быть гораздо большей нагрузкой. Например, в PHP простая загрузка библиотек и выполнение одного вызова заставит скрипт занимать дополнительный 1 МБ оперативной памяти, а сценарии, требующие ответа от внешнего сервера, обычно остаются в памяти намного дольше, чем обычный скрипт. Если вы разрешаете конечным пользователям (а не только администраторам) загружать скрипты, которые выполняют вызовы Stripe API, эта проблема усиливается. Рекомендуется никогда не разрешать пользователям запускать взаимодействие с Stripe API больше, чем это абсолютно необходимо (т. Е. Только Тогда, когда они делают что-то, о чем Stripe должен знать).
- Время безотказной работы — если у Stripe есть какие-либо простои или возникают какие-либо проблемы с подключением между вашим сервером и stripe, ваша информация по-прежнему доступна, и для ваших пользователей нет видимых перерывов в обслуживании.
- Особенности — Это то, что вас интересует здесь, и что в конечном итоге заставляет вас нуждаться в локальной базе данных. Вы можете структурировать данные так, как хотите, что включает в себя такие возможности, как добавление индексов к любым полям, которые вы хотите, чтобы вы могли быстро и эффективно возвращать любую информацию, которую вы хотите в запросе. Вы не ограничены тем, что Stripe позволяет вам делать с их API.
- Расширяемость — Если вы когда-нибудь захотите сменить платежную систему, вы можете легко переключиться на новую, и пользователи даже не заметят, потому что вы извлекли свою собственную базу данных и записи о выставлении счетов из платежной системы. Фактически, если вы хотите, у вас может быть даже несколько платежных процессоров одновременно, отображаемых вашим пользователям в единой системе выставления счетов. Stripe сейчас довольно фантастичен во многих отношениях, но кто знает, куда пойдет компания в долгосрочной перспективе. Иногда некогда отличные компании и их продукты попадают в немилость. Может быть, появится лучший конкурент. И уже есть несколько способов оплаты, которые он не поддерживает, но некоторые из его конкурентов поддерживают: если вы в конечном итоге выйдете на рынок, где предпочтителен один из этих способов оплаты, вам может понадобиться другой платежный процессор.
Чем больше вы думаете об этом, тем больше понимаете, что хранить эту информацию локально — это не только лучшая практика, это огромная выгода, и это немного рискованно не делать этого.
Как это начать?
Сначала создайте в своей собственной базе данных соответствующие таблицы и структуру для событий, которые вы хотите сохранить.
Используя webhooks, всякий раз, когда происходит соответствующее событие, захватите событие, извлеките из него соответствующие данные и сохраните их локально в своей базе данных. Для выставления счета вам нужно будет зафиксировать любое событие, которое потенциально может отражать изменение в счете.
Однако вам не нужно хранить все или даже большую часть данных в каждом событии. Stripe хранит огромное количество данных в каждом событии, и на практике вам нужно очень мало. Я не могу точно сказать, что вам нужно для вашего использования; это зависит от того, какую информацию вы хотите сохранить, что будет зависеть как от того, что вы хотите представить своим пользователям, так и от того, хотите ли вы хранить какую-либо дополнительную информацию за кулисами для вашего собственного внутреннего использования и ведения записей.
Как наверстать упущенное, если вы не сделали этого с самого начала?
В этом случае вам нужно будет перебрать все записи и извлечь соответствующую информацию.
Именно здесь приходят ответы от bobmarksie и urban_raccoons. Они предлагают два предложения двух совершенно разных способов сделать это: bobmarksie предлагает перебирать квитанции, а urban_raccoons предлагает делать это по счетам. Решение от bobmarksie предоставляет подробную информацию с использованием Java, но вы можете сделать это на любом языке.
Независимо от того, как вы выполняете детали, я рекомендую комбинировать оба подхода: перебирать все счета-фактуры и все поступления и связывать их в своей базе данных. Теперь у вас будет полный, актуальный список, и вы можете полагаться на webhooks для обновления вашей локальной базы данных в долгосрочной перспективе.