Java支付网关与Rapyd集成
#教程 #java #payments #fintech

由mdu sibis

付款网关是接受付款的任何数字平台中最重要的组件之一。您的网站或应用需要提供灵活且安全的付款方式才能具有竞争力,并且付款处理功能直接影响转换率。这是一个您无力跳过的领域。

本文展示了如何使用Java和Rapyd Collect API为网站创建付款门。 tutorial's source files are available in this GitHub repo

Rapyd收集API是什么?

Rapyd Collect是一个全球付款接受平台,可让您为许多地区提供各种付款方式和期权。 Rapyd的使命是用您需要的所有付款,支出和业务所需的所有工具来解放全球贸易。 RAPYD收集的API使您可以将Rapyd收集付款集合功能和服务集成到您的电子商务网站和应用中。

Rapyd的网络很广泛,使您可以接受100多个不同国家 /地区的付款。它还具有50多种不同货币的本地支付选项。可以通过借记卡和信用卡,Rapyd Wallet,Global和Local E-Walters,Cash或Bank Redirect收集付款。 Rapyd Collect API还支持订阅计费和发票。

大多数这些功能可通过Rapyd Collect的高度可自定义的结帐页面提供给您。 Rapyd允许您以三种方式实施它:

  • 托管:此选项将站点访问者重定向到Rapyd服务器上托管的结帐页面。这可以说是整合付款收款流的最简单方法。
  • 工具包集成:此选项使您可以使用iframe将Rapyd的结帐嵌入到网站中。
  • API集成:此选项使您可以将RAPYD收集平台直接构建到应用程序中。它要求您在接受付款之前与PCI-DSS compliance见面。

作为PCI level 1服务提供商和英国标准机构(BSI)在information security management中获得认可的公司,Rapyd可以为您处理敏感用户和付款信息。

跟上快速发展的电子商务技术环境仍然是一个挑战,尤其是对于中小型企业而言。委派付款和付款网络安全减轻了您的IT资源和budget的压力。

使用Rapyd实施结帐页面

本教程着重于在线补充商店建立结帐页面,但您可以将其调整到您选择的任何集成开发环境(IDE)或开发工作流程中。

如前所述,您可以使用API​​实现托管,嵌入或内置的Rapyd结帐页面。教程使用第一个选项。

项目先决条件

您需要几件事才能开始编码:

请注意,您需要与Java一起进行一些开发经验才能跟随本教程。

构建您的Java应用程序

在开始构建Java应用程序之前,必须确保将Rapyd帐户设置为 Sandbox 模式。您可以使用工具栏上的开关在环境之间切换:

Switching Rapyd to **Sandbox** mode

您可以使用诸如Notepad之类的应用程序来手动构建类文件,也可以使用更完整的文本编辑器或IDE。本教程使用后者,特别是Apache NetBeans

如果您更喜欢使用替代工具,例如Visual Studio CodeVSCodiumEclipse,则应该没有问题来调整本教程,以适应您的首选方法。 project repo中包含了一组示例和指向类文件的链接。

启动NetBeans并创建一个新的基于Maven的Java Web应用程序:

Creating a new Maven-based Java project

命名您的项目并在提示时设置其位置:

NetBeans name and location

接下来,您需要为项目选择服务器和Java平台,企业版(Java EE)版本。本教程中的项目使用GlassFish和写作时的最新版本Java EE(Jakarta EE 9.1 Web)。由于Java SE JDK的第19版尚未与Glassfish兼容,因此建议您下载并使用JDK 17

Web application server and SDK selection

IDE将初始化项目并创建所有必要的文件夹和文件。初始化后运行该项目是一个好主意,以确保其和您的应用程序服务器已正确设置:

Run your project for the first time

大多数IDE,具体取决于它们的设置方式,将自动在开发人员特定或默认的IDE浏览器中启动该项目。 Netbeans没什么不同。但是,您还可以手动运行浏览器并导航到服务器托管您的应用程序的地址(例如http://localhost:8080/RapydHostExample):

Vivaldi Hello World screen

使用项目侧面面板打开index.html文件。它位于网页下节点。在index.html文件上右键单击此节点,然后单击 Open

Open the  raw `index.html` endraw

用以下代码覆盖index.html内容:

<!DOCTYPE html>

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>International Supplement Shop</title>

</head>

<body>

    <div><h1>Hi! 👋 Welcome to the Best Supplement Shop in The World</h1>

        <p>Try out our new vegan protein shake!</p><hr><h1>Checkout our latest products:</h1><section>

            <div><h3>Vegan Protein Supplement 2Lbs (908 grams)</h3>

                <p>This is a dairy-free protein shake that is easy to digest</p><b>$10</b><br/><a href="Vegan Protein Supplement.jsp">See more</a></div></section>

  </div>

</body>

</html>

网页下创建一个新的JSP文件项目文件夹,并将其命名Vegan Protein Supplement.jsp

Create a new JSP file

用以下代码替换Vegan Protein Supplement.html文件中的模板内容:

<%@page contentType="text/html" pageEncoding="UTF-8"%>

<!DOCTYPE html>

<!DOCTYPE html>

<html>

<head>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Vegan Protein Supplement</title>

</head>

<body>

    <div><h1>Unflavored Vegan Protein Supplement</h1>

        <p>A vegan protein supplement that can be either taken with water as a shake or added to recipes.<br/> 

​     Ideal for vegan athletes trying to build muscle. 

​     Go from Vegan to Vegain with this pea and watermelon seed protein supplement! </p><b>$10</b><br><form action="Purchase" method="POST"><input type="hidden" name="amount" value="100"><input type="submit" value="Purchase" name="submit"></form>

  </div>

</body>

</html>

结帐页面将从Vegan Protein Supplement.jsp 购买按钮。

自定义Rapyd结帐页面

打开Rapyd客户仪仪表板,然后单击左图上的设置项目;然后单击主屏幕上的品牌小部件:

Click on **Settings**

品牌屏幕允许您自定义Rapyd托管结帐页面的外观和感觉:

Rapyd **Branding** for the checkout page

您可以添加和自定义视觉方面,例如以下内容:

  • 徽标:您可以上传徽标的图像。
  • 呼吁行动按钮:您可以设置这些按钮的文本和颜色。
  • 重定向:您可以在交易成功,失败或取消后将客户发送到客户的URL。理想情况下,您应该将其设置为网站的主页。
  • 客户支持:您可以将客户支持和业务信息添加到您的Rapyd付款网关。
  • 页面类型:您可以在托管结帐,保存卡详细信息页面和受益人帐户页面之间进行选择。

要使第一次运行保持简单,请单击钱包图标并取消选中所有其他选项,将其选择为唯一的付款选项:

Rapyd Checkout Page customization

留下其他所有东西。

调用Rapyd结帐页面

要调用Rapyd Checkout页面,您需要创建一个Servlet,该servlet单击“购买”按钮时将调用结帐页面。在项目导航面板中展开源软件包节点,并右键单击主包( IE com.mycompany.rapydcheckoutexample)。在上下文菜单中单击,然后选择 servlet

Create a new Java Servlet

命名servlet(本教程使用的本教程 Checkoutservlet ),然后单击完成按钮。

在编辑窗口中打开servlet,然后用以下代码替换其内容:

package com.mycompany.rapydcheckoutexample;

//import jakarta.servlet.DispatcherType;

//import java.io.IOException;

import jakarta.servlet.annotation.WebServlet;

import jakarta.servlet.http.HttpServlet;

import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

import jakarta.ws.rs.POST;

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

import org.apache.http.client.ResponseHandler;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.util.EntityUtils;



import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

import java.io.IOException;

import java.io.UnsupportedEncodingException;



import java.security.InvalidKeyException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.Base64;

import java.util.Random;





@WebServlet("/Purchase")

public class CheckoutServlet extends HttpServlet{

  String cancelCheckoutURL = "http://example.com/cancel";

  String completeCheckoutURL = "http://example.com/complete";

  String country = "US";

  String currency = "USD";

  String language = "en";  

  public static String hash256(String data) throws NoSuchAlgorithmException {

    MessageDigest md = MessageDigest.getInstance("SHA-256");

    md.update(data.getBytes());

    return bytesToHex(md.digest());

  }



  public static String bytesToHex(byte[]bytes) {

    StringBuffer result = new StringBuffer();

    for (byte byt: bytes)

      result.append(Integer.toString((byt & 0xff) + 0x100, 16).substring(1));

    return result.toString();

  }



  public static String hmacDigest(String msg, String keyString, String algo) {

    String digest = null;

    try {

      SecretKeySpec key = new SecretKeySpec((keyString).getBytes("ASCII"), algo);

      Mac mac = Mac.getInstance(algo);

      mac.init(key);

      

      byte[]bytes = mac.doFinal(msg.getBytes("UTF-8"));

      

      StringBuffer hash = new StringBuffer();

      for (int i = 0; i < bytes.length; i++) {

        String hex = Integer.toHexString(0xFF & bytes[i]);

        if (hex.length() == 1) {

          hash.append('0');

        }

        hash.append(hex);

      }

      digest = hash.toString();

    } catch (UnsupportedEncodingException e) {

      System.out.println("hmacDigest UnsupportedEncodingException");

    }

    catch (InvalidKeyException e) {

      System.out.println("hmacDigest InvalidKeyException");

    }

    catch (NoSuchAlgorithmException e) {

      System.out.println("hmacDigest NoSuchAlgorithmException");

    }

    return digest;

  }



  public static String generateString() {

    int leftLimit = 97;  // letter 'a'

    int rightLimit = 122; // letter 'z'

    int targetStringLength = 10;

    Random random = new Random();

    StringBuilder buffer = new StringBuilder(targetStringLength);

    for (int i = 0; i < targetStringLength; i++) {

      int randomLimitedInt = leftLimit + (int)

        (random.nextFloat() * (rightLimit - leftLimit + 1));

      buffer.append((char)randomLimitedInt);

    }

    String generatedString = buffer.toString();

    

    return (generatedString);

  }

 @Override

 public void doPost(HttpServletRequest request, HttpServletResponse response)

   throws IOException {

    try {

      System.out.println("GetPOS Start");

      String httpMethod = "post";              // get|put|post|delete - must be lowercase

      String urlPath = "/v1/checkout"; 

      String basePath = "https://sandboxapi.rapyd.net"; // hardkeyed for this example

       String salt = generateString(); // Randomly generated for each request.

      long timestamp = System.currentTimeMillis() / 1000L; // Unix time (seconds).

      String accessKey = "0F32811C67FADC15E0ED";          // The access key received from Rapyd.

      String secretKey = "d8abc747ebfec6cb10a049a9904d7c7652cefeb4cafa6304b15a0176ccf4ef19eac4c0ba61ed8f65";          // Never transmit the secret key by itself.

      String bodyString = "{"

        \+ "\"amount\": 10,\n" +

        "\"complete_checkout_url\":" + completeCheckoutURL +",\n" +

        "\"country\":" + country+",\n" +

        "\"currency\":" + currency + ",\n" +

        "\"cancel_checkout_url\":" + cancelCheckoutURL + ",\n" +

        "\"language\":" + language + "}";                   // Always empty for GET; strip nonfunctional whitespace.

                                    // Must be a String or an empty String.

      String toEnc = httpMethod + urlPath + salt + Long.toString(timestamp) + accessKey + secretKey + bodyString;

      System.out.println("String to be encrypted::" + toEnc);

      String StrhashCode = hmacDigest(toEnc, secretKey, "HmacSHA256");

      String signature = Base64.getEncoder().encodeToString(StrhashCode.getBytes());

      HttpClient httpclient = HttpClients.createDefault();

      

      try {

        HttpGet httpget = new HttpGet(basePath + urlPath);

      

        httpget.addHeader("Content-Type", "application/json");

        httpget.addHeader("access_key", accessKey);

        httpget.addHeader("salt", salt);

        httpget.addHeader("timestamp", Long.toString(timestamp));

        httpget.addHeader("signature", signature);

        

        // Create a custom response handler

         ResponseHandler < String > responseHandler = new ResponseHandler < String > () {

           @ Override

          public String handleResponse(

            final HttpResponse response)throws ClientProtocolException,

          IOException {

            int status = response.getStatusLine().getStatusCode();

            HttpEntity entity = response.getEntity();

            

            return entity != null ? EntityUtils.toString(entity) : null;

          }

        };

        

        String responseBody = httpclient.execute(httpget, responseHandler);

        System.out.println("----------------------------------------");

        System.out.println(responseBody);

      } catch (Exception e) {

      

        System.out.println(e.getMessage());

          

        for (StackTraceElement exc : e.getStackTrace()) {

          System.out.println(exc.toString());

        }

      }

    } catch (Exception e) {

      System.out.println(e.getMessage());

          

        for (StackTraceElement exc : e.getStackTrace()) {

          System.out.println(exc.toString());

        }

    }

  }

 }

您现在可以构建您的项目。您会注意到,这是一个三页的过程,从索引页面到产品页面,最后是结帐页面。您的结帐页面应该看起来像:

Rapyd Checkout Page

和恭喜!您已经成功地将Rapyd与可作为付款网关的Java应用程序集成在一起。

结论

在本教程中,您已经了解了Rapyd收集并探讨了如何使用它来构建和插入结帐页面,并将结帐页面插入基于Java的Web Store或应用程序。这是该项目的体系结构的概述:

Rapyd Architecture Diagram

您可以访问GitHub本教程中的complete project source files

有任何想法或问题吗?确保将它们发布在Rapyd Developer Community中。