(Весна) Загрузка Java для приема цифровых платежей с помощью USDC
13 июня 2023 г.Забавно, как, казалось бы, бессмысленное событие в жизни человека может привести к неожиданным переменам. Для меня одно из таких событий произошло в июле 2021 года, когда мой рейс домой задержали настолько, что я заплатил за свой самый первый Uber.
Я был настолько впечатлен полученным опытом, что написал о базовом платежном процессоре в своем «Использование Marqeta для создания платежного сервиса в Spring Boot: практическое руководство". Я продолжал глубже погружаться в платформу Marqeta, написав о том, как -to-fix-it/">создать бонусную карту и даже статью о создании покупайте сейчас, платите позже.
Именно в этот момент я начал говорить с Marqeta о том, чтобы стать частью их инженерной команды. Примерно через шесть недель я повесил шляпу консультанта и начал работать на полную ставку в финтех-инноваторе рынка, который создал первую в мире современную платформу для выпуска карт.
Это было увлекательное путешествие по сложной, извилистой дороге. Мне нравится!
В свободное время я продолжал глубже погружаться в мир web3, и я всегда стремлюсь узнать больше о Fintech. Поэтому для меня естественно исследовать, где пересекаются веб3 и финансовые услуги!
В этой статье я хотел увидеть, насколько легко разработчику web2 использовать Java для выполнения некоторых финтех-транзакций с использованием web3 и USDC в блокчейне Ethereum. Я планирую использовать Circle Java SDK, Java 17 и Spring Boot 3 RESTful API.
О Circle и USDC
Мы не можем говорить о USDC (USD Coin), не упомянув сначала о Circle, поскольку именно они управляют стейблкоином. Компания Circle была основана в 2013 году (примерно в то же время, что и Marqeta) и занималась одноранговыми платежами.
Как частная компания, Circle достигла нескольких ключевых вех:
* Circle Pay (мобильные платежи) позволял пользователям хранить, отправлять и получать традиционные фиатные валюты. Позже они стали службой цифрового кошелька Биткойн, позволяющей потребителям покупать/продавать биткойны. * К 2015 году счет Circle можно будет пополнять в долларах США с помощью кредитных и дебетовых карт Visa и Mastercard, выпущенных в США. Год спустя аналогичная функциональность была распространена на Европу. * В 2018 году Circle привлекла венчурный капитал для создания USDC, пообещав, что ее монета будет обеспечена полностью зарезервированными активами.
USDC — это цифровая (крипто) валюта, привязанная к доллару США (и обеспеченная им). По сути, это означает, что 1 доллар США всегда равен 1 доллару США.
Так почему тогда USDC вместо долларов США?
* USDC можно отправить в любой сумме всего за пару долларов. * USDC можно отправлять по всему миру и почти мгновенно. * Поскольку USDC является цифровой валютой, ее можно отправлять, получать и оплачивать в любое время. Вам не нужно беспокоиться о часах работы банка. * А поскольку USDC является цифровым , для работы с ним существуют API и SDK (что мы и рассмотрим в этой статье).
USDC выпускается частной организацией (это не цифровая валюта центрального банка) и в основном доступен в виде токена Ethereum ERC-20.
С помощью USDC Circle стремится стать революционером, предоставляя клиентам возможность избежать банковских часов, времени обработки и дорогостоящих сборов — и все это при построении бизнеса с цифровой валютой USDC.
Используете USDC для совершения и получения платежей с помощью Java? Да, пожалуйста!
Для этой публикации предположим, что ваш сервис предназначен для тех, кто заинтересован в использовании USDC для выполнения финансовых транзакций. Судя по тому, что вы заметили, текущие сборы, связанные с использованием платформы Circle, позволят вашему сервису оставаться прибыльным.
Все еще пытаясь сохранить реалистичность этого сценария, давайте также предположим, что ваша инфраструктура уходит своими корнями в микросервисы на основе Java, написанные в Spring Boot. Ваша инфраструктура поддерживает проверенную инфраструктуру приложений и сервисов Web2.
Для простоты мы представим новую услугу под названием circle-sdk-demo
, которая будет действовать как интеграция с платформой Circle. В результате мы планируем изучить Java SDK от Circle , который в настоящее время находится в стадии бета-тестирования.
Демонстрация
Прежде чем начать работу со службой, нам нужно перейти на сайт разработчиков Circle и получить ключ API для использования в песочнице:
https://app-sandbox.circle.com/signup/sandbox
Все, что мне нужно было сделать, это заполнить эту форму:
А потом я получил ключ API для их песочницы:
Держите под рукой значение ключа API, так как оно потребуется перед запуском нашего нового сервиса.
Создание службы загрузки Spring
Для этой демонстрации я решил впервые использовать Spring Boot 3. Пока я использовал Spring Initializr в IntelliJ IDEA, результаты моих зависимостей отмечены в следующем файле 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
Вы можете использовать эту ссылку, чтобы определить, как для внешнего заполнения значения circle.api-key
ключом API, созданным выше. Я определенно не рекомендую заполнять значение ключа 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 Boot 3.x выглядит так, как показано ниже:
Добавление службы интеграции Circle
Для связи с платформой 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:
* ПОЛУЧИТЬ /балансы * ПОЧТА/платежи * ПОЛУЧИТЬ /payments/{id}
Для этого примера я просто создал классы BalancesController
и PaymentsController
для размещения этих URI. Более реалистичный дизайн будет использовать подход API First, аналогичный тому, что я отметил в моем «Изучение API-интерфейса. Первый шаблон проектирования».
Сервис circle-sdk-demo в действии
С работающей службой circle-sdk-demo
я смог выполнить некоторые команды cURL для моей локальной службы, которая взаимодействовала с платформой Circle через Java SDK.
Получение списка балансов:
curl --location 'localhost:8585/balances'
Результатом является следующий ответ полезной нагрузки от Circle:
{
"data": {
"available": [],
"unsettled": []
}
}
Создание платежа:
curl --location 'localhost:8585/payments'
--header 'Content-Type: application/json'
--data '{
"currency" : "USD",
"amount" : "1.67",
"settlement_currency": "USD"
}'
Результатом является следующий ответ полезной нагрузки от Circle:
{
"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'
В результате получается следующая полезная нагрузка ответа от Circle:
{
"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"
}
}
На экране журналов разработчиков Circle я вижу сводку всех своих запросов, включая полезную нагрузку ответа:< /p>
Заключение
Читатели моих публикаций могут помнить, что я сосредоточился на следующем заявлении о миссии, которое, как мне кажется, применимо к любому ИТ-специалисту:
<цитата>"Сосредоточьте свое время на предоставлении функций/функций, повышающих ценность вашей интеллектуальной собственности. Используйте фреймворки, продукты и услуги для всего остального».
- Дж. Вестер
Когда я оглядываюсь на каждую свою публикацию по web3, я всегда поражаюсь количеству шагов или сложности, связанных с переходом из точки А в точку Б. Хотя я уверен, что именно так и было, когда я начал работать с web2, я чувствую как стоимость обучения намного выше сейчас. Именно здесь Circle действительно помогает преодолеть разрыв.
В приведенном выше примере я смог использовать Java и Spring Boot для интеграции RESTful API в платформу Circle и начать совершать безопасные онлайн-платежи в режиме реального времени. В результате Circle помогает мне придерживаться моей миссии.
В сфере технологий дела идут быстро, и первые пользователи часто сталкиваются с такими трудностями, как:
* Документация, которая не отшлифована, не точна или даже недоступна * Инструменты и технологии с крутыми кривыми обучения * Невозможность простой интеграции с существующими платформами, службами и приложениями
Из того, что я обнаружил в этом упражнении, Circle избежал этих ловушек, предоставив мне возможность избежать банковских часов, времени обработки и дорогостоящих комиссий при построении моего бизнеса с цифровой валютой USDC. Помимо USDC, он также поддерживает карточные платежи, криптовалюты и другие цифровые способы оплаты. И у него есть явные преимущества перед другими платежными технологиями, такими как Apple Pay, PayPal и Google Pay.
Если вас интересует исходный код этой публикации, его можно найти на GitLab:
https://gitlab.com/johnjvester/circle-sdk-demo
Хорошего дня!
Оригинал