(春季)启动Java接受USDC的数字付款
#网络开发人员 #编程 #web3 #java

Cover Image

有趣的是,一个看似毫无意义的事件如何导致意外的变化。对我来说,其中一项事件发生在2021年7月,当时我的航班被推迟了很多,以至于我为我的第一个Uber付款。

我对我的Leveraging Marqeta to Build a Payment Service in Spring Boot文章中有关基础付款处理器的经历印象深刻。我继续深入研究Marqeta平台,撰写了有关如何进行create a rewards card的文章,甚至是一篇有关构建Abiaoqian的文章。

那时,我开始与Marqeta谈论成为他们的工程团队的一员。大约六个星期后,我挂了顾问帽子,并最初是基于金融科技的市场颠覆者的全职员工,该员工创建了世界上第一个现代卡发行平台。

这是一条充满挑战,蜿蜒的道路的激动人心的旅程。我喜欢它!

在业余时间,我继续深入研究Web3世界,我也总是渴望更多地了解金融科技。因此,探索Web3和Financial Services在哪里相交对我来说是自然的!

在本文中,我想看看Web2开发人员使用Java的容易,以便在以太坊区块链上使用Web3和USDC执行一些金融科技交易。我的计划是使用Circle Java SDK,Java 17和Spring Boot 3 Restful Api。

关于Circle和USDC

我们可以在不首先谈论Circle的情况下谈论USDC(USD硬币),因为它们是管理StableCoin的公司。 Circle成立于2013年(与Marqeta大约同时),重点是点对点付款。

作为一家私人公司,Circle达到了一些关键里程碑:

  • Circle Pay(移动付款)允许用户持有,发送和接收传统的法定货币。后来,他们成为比特币数字钱包服务,允许消费者购买/出售比特币。

  • 到2015年,可以通过美国发行的签证和万事达卡信用卡和借记卡以美元资金来资助一个圆形帐户。一年后,类似的功能扩展到欧洲。

  • 在2018年,Circle提高了风险投资,以建立USDC,并承诺其硬币得到完全保留的资产的支持。

USDC是一种数字(加密)货币,与美元(并支持)美元。基本上,这意味着1个USDC始终等于1美元。

那么为什么USDC那而不是美元?

  • USDC可以以任何数量的价格以几美元的价格发送。

  • USDC几乎可以立即发送。

  • 因为USDC是一种数字货币,因此可以随时发送,接收和解决。您不必担心银行时间。

  • ,并且由于USDC是数字的 - 有一个API和SDK可以使用它(这是我们在本文中探讨的)。

USDC由私人实体(不是中央银行的数字货币)发行,主要作为以太坊ERC-20代币。

使用USDC,Circle的目标是使客户能够避免使用USDC数字货币的业务时避免银行工作时间,处理时间和昂贵的费用。

使用USDC与Java进行付款?是的,请!

对于本出版物,让您的服务符合有兴趣使用USDC进行财务交易的人。根据您的观察,与使用Circle平台相关的当前费用将使您的服务仍然可以盈利。

仍然试图保持这种情况现实,让我们还假设您的基础架构根源在基于Java的微服务中,以Spring Boot编写。您的基础架构支持Web2应用程序和服务的经过验证的基础架构。

为了使事情变得简单,我们将引入一项名为circle-sdk-demo的新服务,该服务将作为与Circle平台的集成。结果,我们计划通过Circle探索Java SDK,该SDK目前仍处于beta状态。

演示

在开始服务之前,我们需要导航到Circle的开发人员网站并获得用于沙盒的API键:

https://app-sandbox.circle.com/signup/sandbox

我要做的就是填写此表格:

Image #2

然后我收到了他们的沙箱的API键:

Image #1

在开始新服务之前,请保持API键值方便。

创建春季启动服务

对于此演示,我想我计划第一次使用Spring Boot 3。当我在Intellij Idea中使用spring initializr时,我的依赖项的结果在以下pom.xml文件中为circle-sdk-demo服务:

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.circle</groupId>
            <artifactId>circle</artifactId>
            <version>0.1.0-beta.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

外部化圆形配置

为了外部化API键值,创建了CircleConfigurationProperties类:

@Data
@Validated
@Configuration("circleConfigurationProperties")
@ConfigurationProperties("circle")
public class CircleConfigurationProperties {
    @NotBlank()
    private String apiKey;
}

供参考,这是我的application.yaml配置文件的副本:

circle:
  api-key: 
server:
  port: 8585
  error:
    include-message: always

您可以使用this link来确定如何使用上面创建的API密钥外部化circle.api-key值的群体。我当然不建议将API键值直接填充到上面的配置文件中。

接下来,我创建了以下CircleConfiguration

@Slf4j
@RequiredArgsConstructor
@Component
public class CircleConfiguration {
    private final CircleConfigurationProperties circleConfigurationProperties;

    @Bean
    public Circle getCircle() {
        log.info("=======================");
        log.info("Initializing Circle SDK");
        log.info("=======================");

        log.info("basePath={}", Circle.SANDBOX_BASE_URL);
        log.info("circle.api-key={}",
                SecurityUtils.maskCredentialsRevealPrefix(
                        circleConfigurationProperties.getApiKey(), 7, '*'));

        Circle circle = Circle.getInstance()
                    .setBasePath(Circle.SANDBOX_BASE_URL)
                    .setApiKey(circleConfigurationProperties.getApiKey());
        log.info("circle={}", circle);

        log.info("==================================");
        log.info("Circle SDK Initialization Complete");
        log.info("==================================");

        return circle;
    }
}

使用API​​键值集,启动circle-sdk-demo spring 3.x服务出现如下所示:

Image #5

添加圆圈集成服务

要与Circle平台进行通信,我创建了一个简单的通行服务,称为CircleIntegrationService

@Slf4j
@Service
public class CircleIntegrationService {
    private final BalancesApi balancesApi = new BalancesApi();
    private final CryptoPaymentIntentsApi cryptoPaymentIntentsApi = new CryptoPaymentIntentsApi();

    public ListBalancesResponse getBalances() throws ApiException {
        ListBalancesResponse listBalancesResponse = balancesApi.listBalances();
        log.info("listBalancesResponse={}", listBalancesResponse);

        return listBalancesResponse;
    }

    public CreatePaymentIntentResponse createPayment(SimplePayment simplePayment) throws ApiException {
        CreatePaymentIntentRequest createPaymentIntentRequest = new CreatePaymentIntentRequest(new PaymentIntentCreationRequest()
                .idempotencyKey(UUID.randomUUID())
                .amount(
                        new CryptoPaymentsMoney()
                                .amount(simplePayment.getAmount())
                                .currency(simplePayment.getCurrency())
                )
                .settlementCurrency(simplePayment.getSettlementCurrency())
                .paymentMethods(
                        Collections.singletonList(
                                new PaymentMethodBlockchain()
                                        .chain(Chain.ETH)
                                        .type(PaymentMethodBlockchain.TypeEnum.BLOCKCHAIN)
                        )
                ));

        CreatePaymentIntentResponse createPaymentIntentResponse = cryptoPaymentIntentsApi.createPaymentIntent(createPaymentIntentRequest);
        log.info("createPaymentIntentResponse={}", createPaymentIntentResponse);

        return createPaymentIntentResponse;
    }

    public GetPaymentIntentResponse getPayment(String id) throws ApiException {
        UUID paymentIntentId = UUID.fromString(id);
        log.info("paymentIntentId={} from id={}", paymentIntentId, id);
        GetPaymentIntentResponse getPaymentIntentResponse = cryptoPaymentIntentsApi.getPaymentIntent(paymentIntentId);
        log.info("getPaymentIntentResponse={}", getPaymentIntentResponse);

        return getPaymentIntentResponse;
    }
}

此服务允许执行以下功能:

  • 获取我的API键的余额列表

  • 创建新付款

  • 通过ID

  • 获得现有付款

创建RESTFUL URI

在示例方案中,circle-sdk-demo将充当我现有服务和Circle平台之间的中间件。接下来,为以下URI创建了基本控制器:

  • 获取/余额

  • 发布/付款

  • 获取/付款/{id}

在此示例中,我只是创建了BalancesControllerPaymentsController课程来容纳这些URI。更现实的设计将采用API的第一种方法,类似于我在Exploring the API-First Design Pattern出版物中指出的。

Circle-SDK Demo服务

在运行circle-sdk-demo服务后,我能够针对我的本地服务执行一些卷曲命令,该命令通过Java SDK与Circle平台进行交互。

获得余额清单:

curl --location 'localhost:8585/balances'

从圈子中产生以下有效载荷响应:

{
    "data": {
        "available": [],
        "unsettled": []
    }
}

创建付款:

curl --location 'localhost:8585/payments' \
--header 'Content-Type: application/json' \
--data '{
    "currency" : "USD",
    "amount" : "1.67",
    "settlement_currency": "USD"
}'

从圈子中产生以下有效载荷响应:

{
    "data": {
        "id": "60b9ff8b-f28c-40cf-9a1c-207d12a5350b",
        "amount": {
            "amount": "1.67",
            "currency": "USD"
        },
        "amountPaid": {
            "amount": "0.00",
            "currency": "USD"
        },
        "amountRefunded": {
            "amount": "0.00",
            "currency": "USD"
        },
        "settlementCurrency": "USD",
        "paymentMethods": [
            {
                "type": "blockchain",
                "chain": "ETH",
                "address": null
            }
        ],
        "fees": null,
        "paymentIds": [],
        "refundIds": [],
        "timeline": [
            {
                "status": "created",
                "context": null,
                "reason": null,
                "time": "2023-03-28T12:26:39.607607Z"
            }
        ],
        "expiresOn": null,
        "updateDate": "2023-03-28T12:26:39.604637Z",
        "createDate": "2023-03-28T12:26:39.604637Z",
        "merchantWalletId": "1013833795"
    }
}

通过ID获得现有付款:

curl --location 'localhost:8585/payments/60b9ff8b-f28c-40cf-9a1c-207d12a5350b' \
--header 'Content-Type: application/json'

从圆圈中导致以下响应有效载荷:

{
    "data": {
        "id": "60b9ff8b-f28c-40cf-9a1c-207d12a5350b",
        "amount": {
            "amount": "1.67",
            "currency": "USD"
        },
        "amountPaid": {
            "amount": "0.00",
            "currency": "USD"
        },
        "amountRefunded": {
            "amount": "0.00",
            "currency": "USD"
        },
        "settlementCurrency": "USD",
        "paymentMethods": [
            {
                "type": "blockchain",
                "chain": "ETH",
                "address": "0xa7fa0314e4a3f946e9c8a5f404bb9819ed442079"
            }
        ],
        "fees": [
            {
                "type": "blockchainLeaseFee",
                "amount": "0.00",
                "currency": "USD"
            }
        ],
        "paymentIds": [],
        "refundIds": [],
        "timeline": [
            {
                "status": "pending",
                "context": null,
                "reason": null,
                "time": "2023-03-28T12:26:42.346901Z"
            },
            {
                "status": "created",
                "context": null,
                "reason": null,
                "time": "2023-03-28T12:26:39.607607Z"
            }
        ],
        "expiresOn": "2023-03-28T20:26:42.238810Z",
        "updateDate": "2023-03-28T12:26:42.345054Z",
        "createDate": "2023-03-28T12:26:39.604637Z",
        "merchantWalletId": "1013833795"
    }
}

从圆圈developer logs screen中,我可以看到我所有请求的摘要,包括响应有效载荷:

Image #3

结论

我的出版物的读者可能还记得我专注于以下任务陈述,我认为可以适用于任何IT专业人士:

将时间集中在提供扩展知识产权价值的功能/功能上。利用其他所有事物的框架,产品和服务。

-J。Vester

当我回顾每个Web3出版物时,我总是惊讶于从A点到点的步骤或复杂性的数量或复杂性。虽然我敢肯定,当我开始使用Web2时,情况就是如此,我觉得学习成本现在要高得多。这是Circle真正弥合差距的地方。

在上面说明的示例中,我能够利用Java和Spring Boot将RESTFUL API集成到Circle平台中,并开始进行实时,在线,安全的付款。结果,Circle正在帮助我遵守任务陈述。

事情在技术领域往往会迅速发展,而早期采用者经常面临以下挑战:

  • 未抛光,准确甚至可用的文档

  • 具有陡峭学习曲线的工具和技术

  • 无法轻松地与现有框架,服务和应用程序集成

根据我在本练习中发现的,Circle避免了这些陷阱 - 在用USDC数字货币建立我的业务时,可以选择避免银行工作时间,处理时间和昂贵的费用。除USDC外,它还支持卡付款,加密货币和其他数字支付方法。它比Apple Pay,PayPal和Google Pay等其他付款技术具有明显的优势。

如果您对本出版物的源代码感兴趣,则可以在Gitlab上找到它:

biaoqian21â

过得非常愉快!