Stellar.org维护着一个分布服务器,可以更轻松地使用federation和compliance服务器来发送和接收付款。 使用分布服务器时,您需要编写的唯一代码是私有服务,用于接收付款通知并响应来自分布和compliance服务器的监管检查。 Payment flow diagram

使用分布服务器时,您通过向其发送HTTP POST请求而不是Horizon服务器来发送付款。 对于简单的交易,它并没有改变很多,但它会使federation和compliance的后续步骤变得更加简单。

创建数据库

分布服务器需要MySQL或PostgreSQL数据库才能跟踪和协调交易和compliance信息。 创建一个名为stellar_bridge的空数据库和一个用户来管理它。 您不需要添加任何表格; 桥接服务器有一个特殊的命令来为您执行此操作

下载并配置Bridge Server

接下来,下载适用于您平台的最新分布服务器。 在任何地方安装可执行文件。 在同一目录中,创建名为bridge.cfg的文件。 这将存储分布服务器的配置。 它应该看起来像:

port = 8006
horizon = "https://horizon-testnet.stellar.org"
network_passphrase = "Test SDF Network ; September 2015"
# We'll fill this in once we set up a compliance server
compliance = ""

# This describes the assets that can be sent and received.
# Repeat this section to add support for more asset types.
[[assets]]
code="USD"
issuer="GAIUIQNMSXTTR4TGZETSQCGBTIF32G2L5P4AML4LFTMTHKM44UHIN6XQ"

[database]
type = "mysql"  # or "postgres" if you created a postgres database
url = "dbuser:dbpassword@/stellar_bridge"

[accounts]
# The secret seed for your base account, from which payments are made
base_seed = "SAV75E2NK7Q5JZZLBBBNUPCIAKABN64HNHMDLD62SZWM6EBJ4R7CUNTZ"
# The account ID that receives payments on behalf of your customers. In this
# case, it is the account ID that matches `base_seed` above.
receiving_account_id = "GAIGZHHWK3REZQPLQX5DNUN4A32CSEONTU6CMDBO7GDWLPSXZDSYA4BU"
# A secret seed that can authorize trustlines for assets you issue. For more,
# see https://stellar.org/developers/guides/concepts/assets.html#controlling-asset-holders
# authorizing_seed = "SBILUHQVXKTLPYXHHBL4IQ7ISJ3AKDTI2ZC56VQ6C2BDMNF463EON65U"
# The ID of the account that issues your assets
issuing_account_id = "GAIUIQNMSXTTR4TGZETSQCGBTIF32G2L5P4AML4LFTMTHKM44UHIN6XQ"

[callbacks]
# The server will send POST requests to this URL to notify you of payments
receive = "http://localhost:8005/receive"

启动服务

在第一次启动服务器之前,需要创建数据库中的表。 使用--migrate-db参数运行桥服务器将确保将所有内容设置为:

./bridge --migrate-db

每次将分布服务器更新为新版本时,都应该再次运行此命令。 如果需要更改任何内容,它将升级您的数据库。

现在您的数据库已完全设置,您可以通过运行以下命令来启动分布服务器:

./bridge

发送付款

分布服务器以HTTP请求的形式接收命令,因此我们可以通过向/payments发送POST请求来测试提交付款。 尝试向帐户GCFXHS4GXL6BVUCXBWXGTITROWLVYXQKQLF4YH5O5JT3YZXCYPAFBJZB发送1美元。 (请记住,接收帐户需要先信任资产。有关详细信息,请参阅发布资产。)

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.util.ArrayList;
import java.util.List;

public class PaymentRequest() {
                public static void main(String [] args) {
                HttpPost paymentRequest = new HttpPost("http://localhost:8006/payment");

                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("id", "unique_payment_id"));
                params.add(new BasicNameValuePair("amount", "1"));
                params.add(new BasicNameValuePair("asset_code", "USD"));
                params.add(new BasicNameValuePair("asset_issuer", "GAIUIQNMSXTTR4TGZETSQCGBTIF32G2L5P4AML4LFTMTHKM44UHIN6XQ"));
                params.add(new BasicNameValuePair("destination", "GCFXHS4GXL6BVUCXBWXGTITROWLVYXQKQLF4YH5O5JT3YZXCYPAFBJZB"));
                params.add(new BasicNameValuePair("source", "SAV75E2NK7Q5JZZLBBBNUPCIAKABN64HNHMDLD62SZWM6EBJ4R7CUNTZ"));

                HttpResponse response = httpClient.execute(paymentRequest);
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                String body =  EntityUtils.toString(entity);
                System.out.println(body);
    }
  }
}

创建服务器以接收付款

Payment flow diagram

在分布服务器配置文件中,您可能已经注意到名为receive的回调URL。 收到付款后,分布服务器将向您指定的URL发送HTTP POST请求。 接收接口的主要职责是更新客户的余额以响应收到付款(因为付款已转到您在POCChain上的帐户)。

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

/**
 * A small Jersey web server for handling callbacks from POCChain services
 */
@Path("/")
public class StellarCallbacks {

  @POST
  @Path("receive")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public Response receive(
    @FormParam("id") String id,
    @FormParam("amount") String amount,
    @FormParam("asset_code") String assetCode,
    @FormParam("asset_issuer") String assetIssuer,
    @FormParam("memo") String memo) {

    // `receive` may be called multiple times for the same payment, so check
    // that you haven't already seen this payment ID. (getPaymentByIdFromDb is
    // a method you’ll need to implement.)
    if (getPaymentByIdFromDb(id)) {
      return Response.ok().build();
    }

    // Because we have one POCChain account representing many customers, the
    // customer the payment is intended for should be in the transaction memo.
    // (getAccountFromDb is a method you’ll need to implement.)
    Customer customer = getAccountFromDb(memo);

    // You need to check the asset code and issuer to make sure it's an asset
    // that you can accept payment to this account for. In this example, we just
    // convert the amount to USD and adding the equivalent amount to the
    // customer balance. You need to implement `convertToUsd()` yourself.
    Double dollarAmount = convertToUsd(amount, assetCode, assetIssuer);
    addToBankAccountBalance(customer, dollarAmount);
    return Response.ok().build();
    System.out.println(String.format(
      "Add %s, USD to account: %s",
      dollarAmount,
      customer));
  }

}

要测试您的接收回拨是否有效,让我们尝试向您的银行帐户名为Amy的客户发送1美元。 (有关使用API发送付款的审核,请查看“开始使用”的第3步。)

Server server = new Server("https://horizon-testnet.stellar.org");

KeyPair source = KeyPair.fromSecretSeed(
  "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4");
KeyPair destination = KeyPair.fromAccountId(
  "GAIGZHHWK3REZQPLQX5DNUN4A32CSEONTU6CMDBO7GDWLPSXZDSYA4BU");
Asset dollar = Asset.createNonNativeAsset("USD", KeyPair.fromAccountId(
    "GAIUIQNMSXTTR4TGZETSQCGBTIF32G2L5P4AML4LFTMTHKM44UHIN6XQ"));

AccountResponse sourceAccount = server.accounts().account(source);
Transaction transaction = new Transaction.Builder(sourceAccount)
  .addOperation(new PaymentOperation.Builder(destination, dollar, "1").build())
  // Use the memo to indicate the customer this payment is intended for.
  .addMemo(Memo.text("Amy"))
  .build();
transaction.sign(source);

try {
  SubmitTransactionResponse response = server.submitTransaction(transaction);
  System.out.println("Success!");
  System.out.println(response);
} catch (Exception e) {
  System.out.println("Something went wrong!");
  System.out.println(e.getMessage());
}

运行上述代码后,您的回调服务器应该记录有关付款的信息。