介绍

  • 有很多不同的支付服务,例如PayPal,Stripe,Authorize.net等,但是在本文中,我将使用Stripe,因为它是最受欢迎,易于使用且集成速度最快的一种。我将向您展示如何在Spring Boot应用程序中使用Stripe以及如何与Angular Web应用程序进行通信。

账户创建

  • 首先,您需要在Stripe.com网站上创建帐户。您无需添加信用卡信息和其他内容,只需验证您的电子邮件地址和电话号码即可使用其服务。
  • 完成此操作后,您应该获取api密钥。转到左侧菜单上的API标签,您将找到可发布密钥秘密密钥。稍后我们将使用这些密钥进行请求。

image.png

  • 在开始编码之前,您需要了解一件非常重要的事情。条带服务基于令牌。当您想对信用卡收费时,您需要创建将信用卡信息作为参数传递的令牌,然后使用创建的令牌作为来源对信用卡收费。所有令牌只能使用一次,因此,如果您尝试使用相同的令牌进行其他操作,则会收到令牌无效或过期的错误消息。
  • 可以使用Stripe中的适当方法在您的后端上生成令牌,但是将信用卡信息直接发送到您的服务器不是一个好习惯,因为有人可以拦截此数据(中间人攻击)。
  • 最好的方法是使用Stripe.js库将信用卡信息直接发送到Stripe 。条带服务器比您的服务器更安全,因此窃取数据的风险很小。这种情况的流程如下(我们将在项目中使用它):
    • 从网页发送数据到Stripe;
    • Stripe返回令牌;
    • 发送令牌到后端服务器;
    • 使用令牌向信用卡收费;
  • 这种方法有两个好处:
    • 您不会将任何敏感数据传递到后端服务器
    • 即使令牌将被中间人拦截,他也无法从此令牌中检索任何信用卡信息

AngularJS部分

因此,让我们开始创建角度项目。使用下一条命令:

ng new stripe-example

此命令将创建新的角度项目。如果无法识别ng,则说明您未安装angular CLI,因此请使用以下命令进行安装

npm install -g @angular/cli

现在,您可以使用以下命令运行项目:

ng serve

应用程序将在端口4200上启动。因此,在浏览器中转到localhost:4200,您应该看到欢迎页面。
我们将创建一个信用卡表格,并在“提交”按钮上将这些数据发送到Stripe生成令牌。让我们向app.component.html文件添加没有任何样式和验证的最简单形式

  1. <form>
  2. <input type="text" placeholder="Credit Card #" name="cardNumber">
  3. <input type="text" placeholder="Expiration Month" name="expMonth">
  4. <input type="text" placeholder="Expiration Year" name="expYear">
  5. <input type="text" placeholder="CVC" name="cvc">
  6. <button (click)="chargeCreditCard()">Submit</button>
  7. </form>

现在我们需要将Stripe.js添加到我们的项目中。为此,我们应该将以下脚本添加到我们的index.hml文件中:

  1. <script type="text/javascript" src="https://js.stripe.com/v2/"></script>
  2. <script type="text/javascript">
  3. Stripe.setPublishableKey('pk_test_XXXXXXXXXXXXXXXXX');
  4. </script>

如您所见,我们在此处设置了前面提到的Publishable Key
现在,将chargeCreditCard()方法添加到app.component.ts中

  1. chargeCreditCard() {
  2. let form = document.getElementsByTagName("form")[0];
  3. (<any>window).Stripe.card.createToken({
  4. number: form.cardNumber.value,
  5. exp_month: form.expMonth.value,
  6. exp_year: form.expYear.value,
  7. cvc: form.cvc.value
  8. }, (status: number, response: any) => {
  9. if (status === 200) {
  10. let token = response.id;
  11. this.chargeCard(token);
  12. } else {
  13. console.log(response.error.message);
  14. }
  15. });
  16. }

当您输入信用卡信息并按提交按钮时,将调用chargeCreditCard()方法,并且将在Stripe端生成令牌。如果某些信息无效,则会收到错误消息。
我们只剩下添加将令牌发送到后端服务器的方法。

  1. chargeCard(token: string) {
  2. const headers = new Headers({'token': token, 'amount': 100});
  3. this.http.post('http://localhost:8080/payment/charge', {}, {headers: headers})
  4. .subscribe(resp => {
  5. console.log(resp);
  6. })
  7. }

从Stripe检索令牌后,应调用此方法。另外,我们需要将Http导入到我们的组件中并将其添加到构造函数中:

  1. import { Http, Headers} from '@angular/http';
  2. ....
  3. constructor(private http: Http) {}

并且不要忘了在imports部分下将HttpModule添加到您的app.module.ts中

  1. import { BrowserModule } from '@angular/platform-browser';
  2. import { NgModule } from '@angular/core';
  3. import {HttpModule} from "@angular/http";
  4. import { AppComponent } from './app.component';
  5. @NgModule({
  6. declarations: [
  7. AppComponent,
  8. ],
  9. imports: [
  10. BrowserModule,
  11. HttpModule
  12. ],
  13. providers: [],
  14. bootstrap: [AppComponent]
  15. })
  16. export class AppModule { }

前端部分完成了!如您所见,我们会将令牌和金额作为标头发送到localhost:8080 / payment / charge。您可以将它们作为请求正文发送或以其他方式发送。我只是使用标头,因为请求主体需要在后端创建相同的对象,但是在本教程中我们不需要它。
当然,它暂时不起作用,因为我们尚未运行后端服务器。因此,让我们继续进行Spring Boot Part。

SpringBoot代码

使用spring-boot-starter-web依赖关系创建新的Maven项目。要在我们的应用程序中使用Stripe,我们应该添加Stripe依赖项:

  1. <dependency>
  2. <groupId>com.stripe</groupId>
  3. <artifactId>stripe-java</artifactId>
  4. <version>5.21.0</version>
  5. </dependency>

让我们用一个映射“付款/收费”的请求来创建我们的PaymentController,以匹配我们从角度应用程序引用的URL。

  1. @RestController
  2. @RequestMapping("/payment")
  3. public class PaymentController {
  4. private StripeClient stripeClient;
  5. @Autowired
  6. PaymentController(StripeClient stripeClient) {
  7. this.stripeClient = stripeClient;
  8. }
  9. @PostMapping("/charge")
  10. public Charge chargeCard(HttpServletRequest request) throws Exception {
  11. String token = request.getHeader("token");
  12. Double amount = Double.parseDouble(request.getHeader("amount"));
  13. return this.stripeClient.chargeCreditCard(token, amount);
  14. }
  15. }

在上面的代码片段中,您可以看到我们正在从从angular应用程序发送的标头中检索条纹令牌和amout。
现在,让我们使用一个方法chargeCreditCard()类创建StripeClient

  1. @Component
  2. public class StripeClient {
  3. @Autowired
  4. StripeClient() {
  5. Stripe.apiKey = "sk_test_XXXXXXXXXXXXXXXXX";
  6. }
  7. public Charge chargeCreditCard(String token, double amount) throws Exception {
  8. Map<String, Object> chargeParams = new HashMap<String, Object>();
  9. chargeParams.put("amount", (int)(amount * 100));
  10. chargeParams.put("currency", "USD");
  11. chargeParams.put("source", token);
  12. Charge charge = Charge.create(chargeParams);
  13. return charge;
  14. }
  15. }

在构造函数中,我们将apiKey分配给Stripe。插入了可发布密钥,我们在这里使用秘密密钥。通过这样做,我们告诉Stripe将此密钥添加到正在发出的每个请求中,因此无需手动添加api密钥请求。

注意:我们将金额乘以100,因为Stripe不需要美元,而是美分。因此,如果我们必须支付$ 100,则应将100000传递给Stripe。同样,该值应始终为整数。 请记住,可以收取的最低金额为50美分。另外,我们正在使用测试API密钥,因此不会实际向您的信用卡收取费用。

如果要在Stripe端保存用户的信用卡,则应使用以下方法创建客户:

  1. public Customer createCustomer(String token, String email) throws Exception {
  2. Map<String, Object> customerParams = new HashMap<String, Object>();
  3. customerParams.put("email", email);
  4. customerParams.put("source", token);
  5. return Customer.create(customerParams);
  6. }

此方法将返回Customer对象,良好的做法是将customerId保存到用户的模型中,以免丢失它。
如果您使用信用卡创建了客户,则无需创建令牌并提示用户输入其信用卡。您可以使用这种方法向现有客户收费,例如:

  1. public Charge chargeCustomerCard(String customerId, int amount) throws Exception {
  2. String sourceCard = Customer.retrieve(customerId).getDefaultSource();
  3. Map<String, Object> chargeParams = new HashMap<String, Object>();
  4. chargeParams.put("amount", amount);
  5. chargeParams.put("currency", "USD");
  6. chargeParams.put("customer", customerId);
  7. chargeParams.put("source", sourceCard);
  8. Charge charge = Charge.create(chargeParams);
  9. return charge;
  10. }

创建客户时,Stripe会将用户的信用卡设置为默认收费来源。因此,您可以获取此来源并将其作为收费来源传递,其方式与我们传递令牌相同。
要做的一件事就是添加一些配置,以避免在从我们的角度应用程序发出请求时避免跨源资源共享(CORS)问题。因此,让我们使用@Configuration注释创建MVCProperties.class

  1. @Configuration
  2. public class MVCProperties extends WebMvcConfigurerAdapter {
  3. @Override
  4. public void addCorsMappings(CorsRegistry registry) {
  5. registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS");
  6. }
  7. }

测试

我们的应用程序的两个部分都已准备就绪,因此我们可以尝试对其进行测试。我将使用具有以下数据的测试信用卡:
image.png
信用卡资料
按“提交”按钮后,您应该在浏览器的控制台中收到有关Charge对象的响应。您也可以打开Stripe帐户,转到“付款”标签,然后会看到$ 100的费用。
image.png
条纹付款
例如,如果我输入无效的有效期限,则Stripe会显示以下消息“您的卡的有效期限无效”。

结论

现在,您知道了如何使用Stripe集成付款,当您在实际项目中遇到此问题时,这对您来说将不是问题。如果您想了解有关所有Stripe方法的更多信息,请访问文档链接
谢谢您阅读本文,我非常感谢。如果您有任何问题,请随时发表评论。这是G itHub上此项目的链接。您也可以在Oril Software GitHub上进行检查。

参考资料