Introdução à API Stripe para Java
1. Visão geral
Stripe é um serviço baseado em nuvem queenables businesses and individuals to receive payments over the internete oferece bibliotecas do lado do cliente (JavaScript e móvel nativo) e bibliotecas do lado do servidor (Java, Ruby, Node.js, etc.).
O Stripe fornece uma camada de abstração que reduz a complexidade do recebimento de pagamentos. Como resultado,we don’t need to deal with credit card details directly – instead, we deal with a token symbolizing an authorization to charge.
Neste tutorial, criaremos um projeto de amostra do Spring Boot que permite aos usuários inserir um cartão de crédito e, posteriormente, cobraremos do cartão uma determinada quantia usandoStripe API for Java.
2. Dependências
Para usarStripe API for Java no projeto, adicionamos a dependência correspondente ao nossopom.xml:
com.stripe
stripe-java
4.2.0
Podemos encontrarits latest version in the Maven Central repository.
Para o nosso projeto de amostra, vamos aproveitar ospring-boot-starter-parent:
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
Também usaremosLombok para reduzir o código clichê, eThymeleaf será o mecanismo de modelo para entrega de páginas da web dinâmicas.
Como estamos usandospring-boot-starter-parent para gerenciar as versões dessas bibliotecas, não precisamos incluir suas versões empom.xml:
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-thymeleaf
org.projectlombok
lombok
Observe queif you’re using NetBeans, you may want to use Lombok explicitly with version 1.16.16, pois um bug na versão do Lombok fornecida com Spring Boot 1.5.2 faz com que o NetBeans gere muitos erros.
3. Chaves de API
Antes de podermos nos comunicar com Stripe e executar cobranças de cartão de crédito, precisamosregister a Stripe account and obtain secret/public Stripe API keys.
Após a confirmação da conta, faremos o login para acessar oStripe dashboard. Em seguida, escolhemos "Chaves da API" no menu do lado esquerdo:
Haverá dois pares de chaves secretas / públicas -one for test and one for live. Vamos deixar essa guia aberta para que possamos usar essas chaves mais tarde.
4. Fluxo Geral
A cobrança do cartão de crédito será realizada em cinco etapas simples, envolvendo o front-end (executado em um navegador), o back-end (nosso aplicativo Spring Boot) e o Stripe:
-
Um usuário acessa a página de checkout e clica em "Pagar com cartão".
-
Um usuário é apresentado à caixa de diálogo de sobreposição de distribuição de faixa, onde preenche os detalhes do cartão de crédito.
-
Um usuário confirma com "Pay
" que irá: -
Envie o cartão de crédito para o Stripe
-
Obtenha um token na resposta que será anexada ao formulário existente
-
Envie esse formulário com o valor, a chave pública da API, o email e o token para nosso back-end
-
-
Nossos contatos de back-end distribuem o token, a quantidade e a chave secreta da API.
-
Verificações de backend Rejeite a resposta e forneça ao usuário o feedback da operação.
Abordaremos cada etapa com mais detalhes nas seções a seguir.
5. Formulário de Check-out
Stripe Checkout é umcustomizable, mobile ready, and localizable widget que renderiza um formulário para apresentar os detalhes do cartão de crédito. Através da inclusão e configuração de “checkout.js“, é responsável por:
-
Renderização da caixa de diálogo de sobreposição de pagamento (acionada após clicar em “Pagar com cartão”)
-
Validação do cartão de crédito
-
Recurso "Lembrar de mim" (associa o cartão a um número de celular)
-
Enviando o cartão de crédito para o Stripe e substituindo-o por um token no formulário anexo (acionado após clicar em "Pagar
")
Se precisarmos exercer mais controle sobre o formulário de checkout do que o fornecido pelo Stripe Checkout, podemos usarStripe Elements.
A seguir, analisaremos o controlador que prepara o formulário e depois o próprio formulário.
5.1. Controlador
Vamos começar criando um controlador paraprepare the model with the necessary information that the checkout form needs.
Primeiro, precisaremoscopy the test version of our public key from the Stripe dashboarde usá-lo para definir STRIPE_PUBLIC_KEY como uma variável de ambiente. Em seguida, usamos esse valor no campostripePublicKey.
Também estamos definindocurrencyeamount (expresso em centavos) manualmente aqui apenas para fins de demonstração, mas em um aplicativo real, podemos definir um produto / id de venda que pode ser usado para buscar valores.
Em seguida, enviaremos para a visualização de checkout que contém o formulário de checkout:
@Controller
public class CheckoutController {
@Value("${STRIPE_PUBLIC_KEY}")
private String stripePublicKey;
@RequestMapping("/checkout")
public String checkout(Model model) {
model.addAttribute("amount", 50 * 100); // in cents
model.addAttribute("stripePublicKey", stripePublicKey);
model.addAttribute("currency", ChargeRequest.Currency.EUR);
return "checkout";
}
}
Em relação às chaves da API Stripe, é possível defini-las como variáveis de ambiente por aplicativo (teste vs. viver).
Como no caso de qualquer senha ou informação sensível, é melhor manter a chave secreta fora do seu sistema de controle de versão.
5.2. Form
O botão "Pagar com cartão" e a caixa de diálogo de checkout são incluídos adicionando um formulário com um script interno, configurado corretamente com atributos de dados:
O script “checkout.js” dispara automaticamente uma solicitação ao Stripe logo antes do envio, que então anexa o token do Stripe e o e-mail do usuário do Stripe como os campos ocultos “stripeToken” e “stripeEmail“ .
Eles serão enviados ao nosso back-end, juntamente com os outros campos do formulário. Os atributos de dados do script não são enviados.
Usamos Thymeleaf para renderizar os atributos “data-key“, “data-amount“ e “data-currency“.
O valor (“data-amount“) é usado apenas para fins de exibição (junto com “data-currency“). Sua unidade é centavos da moeda usada, então a dividimos por 100 para exibi-la.
A chave pública do Stripe é passada para o Stripe depois que o usuário pede para pagar. Do not use the secret key here, as this is sent to the browser.
6. Operação de carga
Para o processamento no servidor, precisamos definir o manipulador de solicitações POST usado pelo formulário de checkout. Vamos dar uma olhada nas classes de que precisaremos para a operação de carga.
6.1. ChargeRequest Entity
Vamos definir o POJOChargeRequest que usaremos como uma entidade comercial durante a operação de carga:
@Data
public class ChargeRequest {
public enum Currency {
EUR, USD;
}
private String description;
private int amount;
private Currency currency;
private String stripeEmail;
private String stripeToken;
}
6.2. Serviço
Vamos escrever uma aulaStripeService paracommunicate the actual charge operation to Stripe:
@Service
public class StripeService {
@Value("${STRIPE_SECRET_KEY}")
private String secretKey;
@PostConstruct
public void init() {
Stripe.apiKey = secretKey;
}
public Charge charge(ChargeRequest chargeRequest)
throws AuthenticationException, InvalidRequestException,
APIConnectionException, CardException, APIException {
Map chargeParams = new HashMap<>();
chargeParams.put("amount", chargeRequest.getAmount());
chargeParams.put("currency", chargeRequest.getCurrency());
chargeParams.put("description", chargeRequest.getDescription());
chargeParams.put("source", chargeRequest.getStripeToken());
return Charge.create(chargeParams);
}
}
Conforme mostrado emCheckoutController,the secretKey field is populated from the STRIPE_SECRET_KEY environment variable that we copied from the Stripe dashboard.
Depois que o serviço foi inicializado, essa chave é usada em todas as operações subsequentes do Stripe.
O objeto retornado pela biblioteca Stripe representacharge operatione contém dados úteis como o id da operação.
6.3. Controlador
Finalmente, vamos escrever ocontroller that will receive the POST request made by the checkout form and submit the charge to Stripe por meio de nossoStripeService.
Observe que o parâmetro "ChargeRequest" é inicializado automaticamente com os parâmetros de solicitação "amount", "stripeEmail" e "stripeToken" incluídos no formulário:
@Controller
public class ChargeController {
@Autowired
private StripeService paymentsService;
@PostMapping("/charge")
public String charge(ChargeRequest chargeRequest, Model model)
throws StripeException {
chargeRequest.setDescription("Example charge");
chargeRequest.setCurrency(Currency.EUR);
Charge charge = paymentsService.charge(chargeRequest);
model.addAttribute("id", charge.getId());
model.addAttribute("status", charge.getStatus());
model.addAttribute("chargeId", charge.getId());
model.addAttribute("balance_transaction", charge.getBalanceTransaction());
return "result";
}
@ExceptionHandler(StripeException.class)
public String handleError(Model model, StripeException ex) {
model.addAttribute("error", ex.getMessage());
return "result";
}
}
Com sucesso, adicionamos o status, o ID da operação, o ID da cobrança e o ID da transação do saldo ao modelo, para que possamos mostrá-los posteriormente ao usuário (Seção 7). Isso é feito para ilustrar alguns dos conteúdos decharge object.
NossoExceptionHandler lidará com exceções do tipoStripeException que são lançadas durante a operação de carga.
Se precisarmos de tratamento de erros mais refinado, podemos adicionar manipuladores separados para as subclasses deStripeException, comoCardException,RateLimitException ouAuthenticationException.
A visualização “result” apresenta o resultado da operação de carga.
7. Mostrando o resultado
O HTML usado para exibir o resultado é um modelo básico do Thymeleaf que exibe o resultado de uma operação de cobrança. O usuário é enviado aqui porChargeController se a operação de carga foi bem-sucedida ou não:
Result
Success!
Id.:
Status:
Charge id.:
Balance transaction id.:
Checkout again
Em caso de sucesso, o usuário verá alguns detalhes da operação de cobrança:
Em caso de erro, o usuário receberá a mensagem de erro retornada pelo Stripe:
8. Conclusão
Neste tutorial, mostramos como usar a API Stripe Java para cobrar um cartão de crédito. No futuro, poderemos reutilizar nosso código do servidor para veicular um aplicativo móvel nativo.
Para testar todo o fluxo de carga, não precisamos usar um cartão de crédito real (mesmo no modo de teste). Em vez disso, podemos contar comStripe testing cards.
A operação de cobrança é uma entre muitas possibilidades oferecidas pela Stripe Java API. The official API reference nos guiará por todo o conjunto de operações.
O código de amostra usado neste tutorial pode ser encontrado emGitHub project.