Как принимать оплату в Bitcoin

Bitcoin становится всё более популярным, и на прошлой неделе я решил им воспользоваться для оплаты за службу компьютерного создания музыки. В данной статье я поделюсь с вами техническими деталями интеграции Bitcoin.

Во-первых, вам нужно выбрать провайдера платёжного сервиса/способ оплаты. Вы можете выбрать одного из этого списка. Они различаются по API и специфичности процесса осуществления платежа, но в целом они похожи. Некоторые из деталей использования, упомянутых ниже, относятся только к Coinbase, которую я выбрал, однако они должны быть похожими и у других провайдеров. Я выбрал Coinbase, так как мне показалось, что это наиболее удобный для разработчиков и довольно простой сервис. Есть у него один баг, который мне пришлось обойти, но в целом он неплохой.

Общий процесс совершения операции (в котором, возможно, заключаются некоторые особенности Coinbase) описан ниже. Заметьте, что я описываю наиболее сложный способ, где у вас есть несколько товаров с различными ценами и количеством. Вы можете воспользоваться html/js кодом, который я использовал на странице своей корзины. С другой стороны, это предположительно наилучший провайдер платёжного сервиса, который не перенаправляет пользователя на внешние страницы, а просто использует диалог javascript.

  1. Разместите специальную кнопку "Оплата с помощью Bitcoin" на странице оплаты.
  2. Её нажатие вызывает появление бланка и, таким образом, запускает конечный процесс оплаты.
  3. Серверный код сохраняет новую покупку/заказ в базе банных и возвращает её ID.
  4. Затем серверный код обращается к интерфейсу способа оплаты, сообщая ему ID заказа (или иные данные приложения пользователя) и цену, а затем получает код для подтверждения операции.
  5. Цена может быть указана в BTC или любой другой валюте. В зависимости от API, Вы, возможно, захотите или же вам понадобится конвертировать установленную цену в ходовой валюте в BTC перед тем, как передать её с помощью API. Если вы это делаете, убедитесь, что данные о курсах конверсии какое-то время находятся в вашем кэше, чтобы каждый раз их не искать. Провайдеры могут осуществлять конвертацию автоматически, но если вы хотите показать её пользователю впервые, возможно, вы захотите произвести конвертацию самостоятельно.
  6. После того, как код поступил на компьютер пользователя, javascript его обрабатывает и открывает диалог (с помощью js функции/события, которая предоставляется провайдером).
  7. Диалог может содержать несколько вариантов оплаты, однако обычно в нём отображается платёжный адрес Bitcoin, на который пользователю нужно отправить деньги. Сделать это можно с помощью мобильного телефона либо электронного кошелька.
  8. После завершения операции, ваше приложение обращается к обратному URL-адресу, в котором содержится ID заказа, указанный вами при создании кода. Далее вы можете подтвердить покупку и отправить приобретённые товары.
  9. Затем диалоговое окно автоматически закрывается (либо пользователь нажимает на кнопку "Операция завершена"). На этом этапе вам нужно послать (ajax) запрос, который очищает корзину и перенаправляет вас на страницу благодарности.

Обратите внимание, что в документации провайдера платёжного сервиса указаны все детали проведения операции. Ниже я приведу примеры некоторых особенностей Coinbase и Java.

Обычным способом, описываемым в документах, является размещение на странице кнопки с заранее заданным кодом. Это не подойдёт, если вам понадобится увеличить количество товара или заказать товары различного типа. Вот почему вам следует динамически сгенерировать код для кнопки. Однако библиотека javascript предоставляет такую возможность лишь на странице загрузки. Так что мне пришлось скопировать уменьшенную версию javascript кода и обратиться к нему, когда код обратно поступил на мой компьютер. Вот полный javascript код (вызываемый при нажатии пользователем кнопки "Оплатить с помощью Bitcoin").

$(document).ready(function() {
 $("#payWithBitcoin").click(function() {
  var email = $("#email").val();
  if (${!userLoggedIn} && (!email || email.length == 0 || email.indexOf("@") == -1)) { // здесь простая проверка; полная - на сервере
   alert("Please enter a valid email");
  } else {
   $.post("${root}/cart/bitcoinCheckout", {email: email},function(data) {
    $("#bitcoinPurchase").attr("data-code", data);
    $(".coinbase-button").each(function (b, d) {
     var f, g, h, i, j, k;
     return f = $(d), h = f.data(), h.referrer = document.URL, j = $.param(h), g = f.data("code"), k = f.data("width") || 195, i = f.data("height") || 46, f.data("button-style") !== "none" &amp;&amp; f.replaceWith("<iframe src="" +="" c="" +"="" buttons="" "="" g="" "?"="" j="" ""="" id="coinbase_button_iframe_" +""="" name="coinbase_button_iframe_" style="width: " k="" +"px;="" height:="" i="" "px;="" border:="" none;="" overflow:="" hidden;"="" allowtransparency="true" frameborder="0" scrolling="no"></iframe>"), $("body").append("<iframe src="https://coinbase.com/buttons/" +="" g="" "="" widget?"="" j="" ""="" id="coinbase_modal_iframe_" name="coinbase_modal_iframe_" style="background-color: transparent; border: 0px none transparent; overflow: hidden; display: none; position: fixed; visibility: visible; margin: 0px; padding: 0px; left: 0px; top: 0px; width: 100%; height: 100%; z-index: 9999;" allowtransparency="true" frameborder="0" scrolling="no"></iframe>");
    });
    $("#coinbase_modal_iframe_" + data).load(function() {
     $(document).trigger("coinbase_show_modal", data);
    });
   });
  }
 });

 $(document).on("coinbase_payment_complete", function(event, code){
  $.post("${root}/cart/clear", function() { //очищает содержимое корзины
   window.location = "/?message=Checkout successful. Check your email.";
  });
 });
});

<a id="payWithBitcoin" href="javascript:void(0);"><imgsrc="${staticroot} img="" bitcoin.png"=""></imgsrc="${staticroot}></a>
<div class="coinbase-button" id="bitcoinPurchase" data-button-style="none"></div>
<script src="https://coinbase.com/assets/button.js" type="text/javascript"></script>

Ещё о чём вам следует помнить, - это о том, что не существует официальных клиентских приложений - вам нужно собственноручно вызывать API REST. Конечно, это просто. Вы можете использовать RestTemplate или Jackson.

public String getButtonCode(BigDecimal price, long purchaseId) {
 HttpHeaders headers = new HttpHeaders();
 headers.setContentType(MediaType.APPLICATION_JSON);
 ButtonRequest buttonRequest = new ButtonRequest(); //это объект-значение, специально заданный для этого запроса
 buttonRequest.setCurrency("btc");
 buttonRequest.setCustom(String.valueOf(purchaseId));
 buttonRequest.setPrice(price.toPlainString());
 buttonRequest.setType("buy_now");
 buttonRequest.setName("Computer-generated tracks");
 ResponseEntity entity = template.postForEntity("https://coinbase.com/api/v1/buttons?api_key=" + coinbaseKey, buttonRequest, String.class);
 String json = entity.getBody();
 try {
  JsonNode node = jsonMapper.readTree(json);
  return node.get("button").get("code").asText();
 } catch (IOException e) {
  throw new IllegalStateException(e);
 }
}

И наконец, когда обратный URL-адрес уже вызван, вам нужно получить ID заказа и завершить оплату.

@RequestMapping("/confirmBitcoinPurchase")
@ResponseBody
public void confirmBitcoin(@RequestBody String json) throwsException {
 JsonNode root = mapper.readTree(json);
 JsonNode order = root.get("order");
 if (order.get("status").asText().equals("completed")) {
  String paymentId = order.get("id").asText();
  .....
 }
}

В общем, чтобы разобраться во всём этом, потребуется какое-то время. Предыдущий опыт интеграции провайдера платёжных сервисов будет лишь плюсом, но единственное важное различие заключается в том, что вы не предоставляете провайдеру никакой личной информации о пользователе (например, реквизиты кредитной карточки). Вместо этого, пользователь осуществляет платёж на указанный bitcoin-адрес, который обрабатывается провайдером. Когда бы ни осуществлялась операция, провайдер запрашивает ваш URL.

Затем вы можете получить свои деньги путём банковского перевода либо перечислить их на свой собственный bitcoin-кошелёк.

Bozhidar BOZHANOV

Версия для печатиВерсия для печати

Рубрики: 

  • 1
  • 2
  • 3
  • 4
  • 5
Всего голосов: 0
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Комментарии

Называйте меня занудой, но приведённый код — это не чистый JS, а активно юзающий jQuery, про подключение которой автор почему-то умолчал. А зря.

Ну и если javascript — это библиотека (sic!), то пойду-ка я проверю, не выпустили ли новую версию библиотеки ассемблер для x86.

Аватар пользователя savely

Ну, это ж перепост. Перевели не думая... А претензии  - к автору. :))

Ну, это ж перепост. Перевели не думая... А претензии  - к автору. :))

Это понятно. Но на кой же переводить что-либо сомнительного качества?