Биткойн набирает популярность, и на прошлой неделе я решил использовать его как способ оплаты для моего музыкального музыкального сервиса . Почему я решил сделать это, подробно описано здесь (оплата требуется только для коммерческого использования музыки), но здесь я поделюсь техническими деталями для реализации интеграции биткойнов.
Во-первых, вам нужно выбрать платежный шлюз / провайдера. Вы можете выбрать один из этого списка . Они отличаются с точки зрения их API и конкретного потока, но общий поток должен быть почти одинаковым. Некоторые из деталей реализации ниже относятся только к тому, что я выбрал — Coinbase — но они должны быть похожи для других провайдеров. Я выбрал Coinbase, потому что он казался наиболее удобным для разработчиков и простым. В нем есть одна ошибка, которую мне пришлось обойти, но кроме этого все в порядке.
Общий поток (вероятно, содержащий некоторые особенности Coinbase) ниже. Обратите внимание, что я описываю самый сложный сценарий, когда у вас есть несколько предметов с переменными ценами и количеством. Вы можете использовать код html / js, который я использовал на своей странице корзины . С другой стороны, предполагается, что поставщик платежей в лучшем случае не перенаправляет пользователя на внешние страницы и использует просто диалоговое окно javascript.
- Разместите пользовательскую кнопку «Оплатить биткойнами» на странице оформления заказа
- Нажатие на нее отправляет форму и, таким образом, запускает внутренний процесс оформления заказа.
- Внутренний код сохраняет новую покупку / заказ в базе данных и возвращает его идентификатор
- Затем внутренний код вызывает API платежного шлюза, предоставляя идентификатор заказа (или любые пользовательские данные приложения) и цену, и получает код для идентификации транзакции.
- Цена может быть указана в BTC или в любой валюте. В зависимости от API вам может потребоваться / необходимо конвертировать фиксированную цену в популярной валюте в BTC, прежде чем передавать ее через API. Если вы это сделаете, не забудьте на некоторое время кэшировать показатели конверсии — не нужно каждый раз получать их. Поставщики могут выполнять это преобразование автоматически, но если вы хотите сначала отобразить его для пользователя, вы можете выполнить преобразование самостоятельно.
- При возврате кода во внешний интерфейс javascript получает его и открывает диалоговое окно (используя функцию / событие js, предоставленное провайдером).
- Диалог может содержать несколько вариантов оплаты, но обычно он показывает адрес платежа в биткойнах, на который пользователь должен отправить деньги. Он может сделать это с помощью своего мобильного или настольного кошелька.
- После завершения транзакции в вашем приложении вызывается URL-адрес обратного вызова, который содержит идентификатор заказа, который вы передали при создании кода. Затем вы можете подтвердить покупку и отправить купленные товары.
- Затем диалоговое окно автоматически закрывается (или пользователь нажимает «транзакция завершена»). В этот момент вам необходимо отправить (ajax) запрос, который очищает содержимое корзины, и перенаправить на страницу «Спасибо».
Обратите внимание, что документация поставщика платежа должна содержать все детали реализации. Ниже я поделюсь некоторыми особенностями моего случая: Coinbase и Java:
Сценарий по умолчанию, описанный в документации, заключается в размещении кнопки с предопределенным кодом на странице. Это не работает, если вам нужно увеличить количество или иметь несколько предметов. Вот почему вы должны динамически генерировать код кнопки. Но библиотека javascript обрабатывает это только при загрузке страницы. Поэтому мне пришлось скопировать некоторый минимизированный код JavaScript и вызывать его, когда код возвращается из серверной части. Вот весь код javascript (вызывается, когда пользователь нажимает «Pay with bitcoin»):
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
$(document).ready(function() { $( '#payWithBitcoin' ).click(function() { var email = $( '#email' ).val(); if (${!userLoggedIn} && (!email || email.length == 0 || email.indexOf( '@' ) == - 1 )) { // simple validation here; actual - on the server 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' && f.replaceWith( '<iframe src=' ' + c + ' /buttons/ ' + g + ' ? ' + j + ' ' id=' coinbase_button_iframe_ ' + g + ' ' name=' coinbase_button_iframe_ ' + g + ' ' style=' width: ' + k + ' px; height: ' + i + ' px; border: none; overflow: hidden; ' scrolling=' no ' allowtransparency=' true ' frameborder=' 0 '></iframe>' ), $( 'body' ).append( '<iframe src=' https: //coinbase.com/buttons/' + g + '/widget?' + j + '' id='coinbase_modal_iframe_' + g + '' name='coinbase_modal_iframe_' + g + '' 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;' scrolling='no' allowtransparency='true' frameborder='0'></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() { //clear the contents of the cart window.location = '/?message=Checkout successful. Check your email.' ; }); }); }); |
1
2
3
|
< a id = 'payWithBitcoin' href = 'javascript:void(0);' >< img src = '${staticRoot}/img/bitcoin.png' /></ a > < div class = 'coinbase-button' id = 'bitcoinPurchase' data-button-style = 'none' ></ div > |
Еще одна вещь, которую нужно иметь в виду, это отсутствие официальных клиентов — вам нужно вызвать RESTful API вручную. Это просто, конечно. Вы можете использовать RestTemplate и Джексона, например.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
public String getButtonCode(BigDecimal price, long purchaseId) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); ButtonRequest buttonRequest = new ButtonRequest(); //this is a value-object specifically defined for this request buttonRequest.setCurrency( 'btc' ); buttonRequest.setCustom(String.valueOf(purchaseId)); buttonRequest.setPrice(price.toPlainString()); buttonRequest.setType( 'buy_now' ); buttonRequest.setName( 'Computer-generated tracks' ); ResponseEntity<String> 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 обратного вызова, вам необходимо получить идентификатор заказа и завершить платеж:
01
02
03
04
05
06
07
08
09
10
|
@RequestMapping ( '/confirmBitcoinPurchase' ) @ResponseBody public void confirmBitcoin( @RequestBody String json) throws Exception { JsonNode root = mapper.readTree(json); JsonNode order = root.get( 'order' ); if (order.get( 'status' ).asText().equals( 'completed' )) { String paymentId = order.get( 'id' ).asText(); ..... } } |
В целом, требуется некоторое время, чтобы выяснить. Предыдущий опыт интеграции провайдера платежей был бы плюсом, но есть одно важное отличие: вы не предоставляете ничего конкретного пользователя провайдеру платежей (например, данные кредитной карты). Вместо этого пользователь осуществляет платеж по целевому адресу биткойна, который обрабатывается поставщиком платежа. Всякий раз, когда транзакция завершена, провайдер вызывает ваш URL. Затем вы можете получить деньги через платежный шлюз либо с помощью банковского перевода, либо перечислив их на свой биткойн-кошелек.
Ссылка: Как принимать платежи в биткойнах от нашего партнера по JCG Божидара Божанова в блоге на техническом блоге Божо .