Introduktion til Stripe API til Java

1. Oversigt

Stripe er en skybaseret tjeneste, der gør det muligt for virksomheder og enkeltpersoner at modtage betalinger over internettet og tilbyder både klientsidesbiblioteker (JavaScript og native mobile) og serversidesbiblioteker (Java, Ruby, Node.js osv.).

Stripe giver et abstraktionslag, der reducerer kompleksiteten ved at modtage betalinger. Som resultat, vi behøver ikke at behandle kreditkortoplysninger direkte - i stedet behandler vi et token, der symboliserer en tilladelse til at opkræve.

I denne vejledning opretter vi et eksempel på et Spring Boot-projekt, der giver brugerne mulighed for at indtaste et kreditkort og senere opkræve kortet for et bestemt beløb ved hjælp af Stripe API til Java.

2. Afhængigheder

For at gøre brug af Stripe API til Java i projektet føjer vi den tilsvarende afhængighed til vores pom.xml:

 com.stripe stripe-java 4.2.0 

Vi kan finde den nyeste version i Maven Central-arkivet.

Til vores prøveprojekt vil vi udnytte spring-boot-starter-parent:

 org.springframework.boot spring-boot-starter-parent 2.2.6.RELEASE 

Vi bruger også Lombok til at reducere kedelpladekoden, og Thymeleaf vil være skabelonmotoren til levering af dynamiske websider.

Da vi bruger spring-boot-starter-parent for at administrere versionerne af disse biblioteker behøver vi ikke medtage deres versioner i pom.xml:

 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok 

Noter det hvis du bruger NetBeans, kan du muligvis bruge Lombok eksplicit med version 1.16.16, da en fejl i versionen af ​​Lombok leveret med Spring Boot 1.5.2 får NetBeans til at generere mange fejl.

3. API-nøgler

Før vi kan kommunikere med Stripe og udføre kreditkortafgifter, skal vi registrer en Stripe-konto og få hemmelige / offentlige Stripe API-nøgler.

Efter at have bekræftet kontoen logger vi ind for at få adgang til Stripe-dashboardet. Vi vælger derefter “API-nøgler” i menuen til venstre:

Der vil være to par hemmelige / offentlige nøgler - en til test og en til live. Lad os lade denne fane være åben, så vi kan bruge disse nøgler senere.

4. Generelt flow

Afgiften på kreditkortet sker i fem enkle trin, der involverer frontend (køres i en browser), back-end (vores Spring Boot-applikation) og Stripe:

  1. En bruger går til kassen og klikker på "Betal med kort".
  2. En bruger præsenteres med en Stripe Checkout overlay-dialog, hvor den udfylder kreditkortoplysningerne.
  3. En bruger bekræfter med "Betal", som vil:
    • Send kreditkortet til Stripe
    • Få et token i svaret, der føjes til den eksisterende form
    • Indsend denne formular med beløb, offentlig API-nøgle, e-mail og token til vores back-end
  4. Vores back-end-kontakter Stripe med tokenet, mængden og den hemmelige API-nøgle.
  5. Back-end-kontrol Stripesvar og give brugeren feedback om operationen.

Vi vil dække hvert trin mere detaljeret i de følgende afsnit.

5. Kasseformular

Stripe Checkout er en tilpassbar, mobil klar og lokaliserbar widget, der gengiver en formular til introduktion af kreditkortoplysninger. Gennem inkludering og konfiguration af “checkout.js“, Det er ansvarligt for:

  • Gengivelse af knappen "Betal med kort"

  • Gengivelse af dialog med betalingsoverlay (udløst efter klik på "Betal med kort")

  • Validering af kreditkort
  • "Husk mig" -funktionen (knytter kortet til et mobilnummer)
  • Afsendelse af kreditkort til Stripe og udskiftning med et token i den vedlagte form (udløst efter klik på "Betal")

Hvis vi har brug for at udøve mere kontrol over kassen, end Stripe Checkout giver, kan vi bruge Stripe Elements.

Dernæst analyserer vi den controller, der forbereder formularen og derefter selve formularen.

5.1. Controller

Lad os starte med at oprette en controller til forberede modellen med de nødvendige oplysninger, som kassen har brug for.

Først skal vi kopier testversionen af ​​vores offentlige nøgle fra Stripe-dashboardet og brug den til at definere STRIPE_PUBLIC_KEY som en miljøvariabel. Vi bruger derefter denne værdi i stribePublicKey Mark.

Vi sætter også ind betalingsmiddel og beløb (udtrykt i cent) manuelt her kun til demonstrationsformål, men i en reel applikation kan vi indstille et produkt / salgs-id, der kan bruges til at hente de faktiske værdier.

Derefter sendes vi til kassen, som indeholder kassen:

@Controller offentlig klasse CheckoutController {@Value ("$ {STRIPE_PUBLIC_KEY}") privat streng stripePublicKey; @RequestMapping ("/ checkout") offentlig streng checkout (modelmodel) {model.addAttribute ("beløb", 50 * 100); // i cents model.addAttribute ("stripePublicKey", stripePublicKey); model.addAttribute ("valuta", ChargeRequest.Currency.EUR); returner "kassen"; }}

Med hensyn til Stripe API-nøgler kan du definere dem som miljøvariabler pr. Applikation (test vs. live).

Som det er tilfældet med enhver adgangskode eller følsomme oplysninger, er det bedst at holde den hemmelige nøgle ude af dit versionskontrolsystem.

5.2. Form

Knappen “Betal med kort” og checkout-dialogen er inkluderet ved at tilføje en formular med et script inde, korrekt konfigureret med dataattributter:

  Pris: 

Det "checkout.js”Script udløser automatisk en anmodning til Stripe lige inden indsendelsen, som derefter tilføjer Stripe-token og Stripe-bruger-e-mailen som de skjulte felter“stripeToken”Og“stribeE-mail“.

Disse sendes til vores back-end sammen med de andre formularfelter. Attributterne for scriptdata indsendes ikke.

Vi bruger Thymeleaf til at gengive attributterne “datanøgle“, “datamængde“Og“data-valuta“.

Beløbet ("datamængde“) Bruges kun til visningsformål (sammen med“data-valuta“). Dens enhed er cent af den brugte valuta, så vi deler den med 100 for at vise den.

Den offentlige stripe-nøgle videregives til Stripe, efter at brugeren beder om at betale. Brug ikke den hemmelige nøgle her, da denne sendes til browseren.

6. Opladning

Til behandling af serversiden er vi nødt til at definere den POST-anmodningshåndterer, der bruges i kassen. Lad os se på de klasser, vi har brug for til opladningsoperationen.

6.1. ChargeRequest-enhed

Lad os definere ChargeRequest POJO, som vi vil bruge som en forretningsenhed under afgiftsoperationen:

@Data public class ChargeRequest {public enum Currency {EUR, USD; } privat strengbeskrivelse; privat int beløb privat valuta; privat strengstribeE-mail; private String stripeToken; }

6.2. Service

Lad os skrive en StripeService klasse til kommunikere den faktiske opladning til Stripe:

@Service offentlig klasse StripeService {@Value ("$ {STRIPE_SECRET_KEY}") privat streng secretKey; @PostConstruct offentlig ugyldig init () {Stripe.apiKey = secretKey; } public Charge charge (ChargeRequest chargeRequest) kaster AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {Map chargeParams = new HashMap (); chargeParams.put ("beløb", chargeRequest.getAmount ()); chargeParams.put ("valuta", chargeRequest.getCurrency ()); chargeParams.put ("beskrivelse", chargeRequest.getDescription ()); chargeParams.put ("kilde", chargeRequest.getStripeToken ()); return Charge.create (chargeParams); }}

Som det blev vist i CheckoutController, det secretKey feltet er befolket fra miljøvariablen STRIPE_SECRET_KEY, som vi kopierede fra Stripe-dashboardet.

Når tjenesten er initialiseret, bruges denne nøgle i alle efterfølgende Stripe-operationer.

Objektet, der returneres af Stripe-biblioteket, repræsenterer opladningsoperationen og indeholder nyttige data som f.eks. Operations-id.

6.3. Controller

Lad os endelig skrive controller, der modtager POST-anmodningen fra kassen, og sender gebyret til Stripe via vores StripeService.

Bemærk, at “ChargeRequest”Parameter initialiseres automatisk med anmodningsparametrene“beløb“, “stribeE-mail“Og“stripeToken”Inkluderet i formularen:

@Controller offentlig klasse ChargeController {@Autowired privat StripeService betalingsservice; @PostMapping ("/ charge") offentlig strenggebyr (ChargeRequest chargeRequest, modelmodel) kaster StripeException {chargeRequest.setDescription ("Eksempel på gebyr"); 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 ()); returner "resultat"; } @ExceptionHandler (StripeException.class) public String handleError (Model model, StripeException ex) {model.addAttribute ("error", ex.getMessage ()); returner "resultat"; }}

Efter succes tilføjer vi status, operations-id, gebyr-id og balancetransaktion-id til modellen, så vi senere kan vise dem til brugeren (afsnit 7). Dette gøres for at illustrere noget af indholdet af opladningsobjektet.

Vores Undtagelse Håndterer vil behandle undtagelser af typen StripeException der smides under opladningsoperationen.

Hvis vi har brug for mere finkornet fejlhåndtering, kan vi tilføje separate håndterere til underklasser af StripeException, såsom CardException, RateLimitException, eller AuthenticationException.

Det "resultat”-Visningen gengiver resultatet af opladningsoperationen.

7. Viser resultatet

HTML'en, der bruges til at vise resultatet, er en grundlæggende Thymeleaf-skabelon, der viser resultatet af en opladningshandling. Brugeren sendes her af ChargeController om opladningen var vellykket eller ej:

   Resultat 

Succes!

Id .: Status: Charge id .: Balance transaction id .: Checkout igen

Efter succes vil brugeren se nogle detaljer om opladningsoperationen:

Ved fejl vil brugeren blive præsenteret for fejlmeddelelsen, som returneres af Stripe:

8. Konklusion

I denne vejledning har vi vist, hvordan man bruger Stripe Java API til at opkræve et kreditkort. I fremtiden kunne vi genbruge vores serverside-kode til at betjene en indbygget mobilapp.

For at teste hele opladningsstrømmen behøver vi ikke bruge et rigtigt kreditkort (selv i testtilstand). Vi kan stole på Stripe-testkort i stedet.

Opladningsoperationen er en af ​​mange muligheder, som Stripe Java API tilbyder. Den officielle API-reference vil guide os gennem hele række operationer.

Eksempelkoden, der bruges i denne vejledning, kan findes i GitHub-projektet.