(Весна) Загрузка Java для приема цифровых платежей с помощью USDC

(Весна) Загрузка 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

Хорошего дня!


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE