支付类交易

提交支付

支付是区块链系统的一个主要功能,实现账号之间点对点的电子资源转移。

在井通系统中,资源的转移通过账号地址即可实现,无需用户的业务信息。在井通系统中,用户不仅可以支付自己拥有的资源, 也可以选择支付自己账号中没有的资源。当用户支付自己账号中没有的资源时,需要提交支付路径查询并选择相应支付路径。 系统根据用户账号中含有资源,同时在系统中选择对应的支付路径进行资产替换,实现目标资产的支付。 支付路径的实现依赖于多资产的撮合算法。具体请参考查询支付路径。如果支付路径不存在,则支付无法进行。

支付操作对象初始化时需要一个井通账号对象,必须提交的参数有对方的井通地址和支付的金额。 支付操作还可以设定操作模式(同步或异步)和一个操作单号。

支付操作中也可以使用setMemo设定一些注释字段。

井通系统中支付交易收取相应的SWT手续费,即使交易失败。

目前,井通环境中只有一个井通银关,所以资产的支付是一个银关之间资产的交易, 一个银关下的同一种资产的支付可以实现直接支付,无需路径。 同时,在井通系统中SWT没有发行银关,支付时无需指定发行银关

Java Example

// construct source wallet
Wallet wallet1 = new Wallet("snqFcH......pQYzxEEbW");

// prepare payment amount
Amount amt = new Amount();
amt.setIssuer("");
amt.setCurrency("SWT");
amt.setValue(1.1);

// create payment operation
PaymentOperation op = new PaymentOperation(wallet1);
op.setDestAddress("jnYcyWcn......z62iMQSfaSXUx");
op.setAmount(amt);
op.setMemo("Test payment on 20161117");
// if not set a client id, PaymentOperation will assign one
op.setClientId("20611171957");
// sync mode
op.setValidate(true);

// submit payment
op.submit(new PaymentListener() {
    @override
    public void onComplete(result) {
        // process result
    }
});

Python Example

# construct source wallet
wallet1 = Wallet("shVC2gdG......gijqk4EsuqDF");

# prepare payment amount
amt = Amount(10, "CNY", "jBciDE8Q3uJ......iUNM775AMKHEbBLS")

# create payment operation
op = PaymentOperation(wallet1);
op.setDestAddress("jnYcyWcn......z62iMQSfaSXUx");
op.setMemo("Test payment on 20161117");
op.setAmount(amt);
op.setClientId("201611171957");
op.setValidate(true);

# submit payment
ret = op.submit();

PHP Example

// construct source wallet
$wallet1 = new Wallet('snwjtucx9......MbVz8hFiK9');

// prepare payment amount
$amount = new Amount('1.0', 'USD', 'jBciDE8Q3uJ......iUNM775AMKHEbBLS');

// create payment operation
$op = new PaymentOperation($wallet1);
$op->setAmount($amount);
$dest_address = 'j......RWn96DkukG4bwdtyTh';
$op->setDestAddress($dest_address);
$op->setMemo("Test payment on 20161117");
$op->setClientId('20611171957');
// sync mode
$op->setValidate(true);

// submit payment
$res = $op->submit();

Node.JS Example

// construct source wallet
var JingtumSDK = require('jingtum-sdk');
var Wallet = JingtumSDK.Wallet;
var Amount = JingtumSDK.Amount;

var wallet1 = new Wallet('shNK......y5W5kK');

// prepare payment amount
var amt = new Amount('0.01', 'SWT', '');

// create payment operation
var op = new JingtumSDK.PaymentOperation(wallet1);
op.setDestAddress('jp53t......DucnwVk');
op.setAmount(amt);
op.setMemo("Test payment on 20161117");

// if not set, PaymentOperation will assign one
op.setClientId("20611171957");
// sync mode
op.setValidate(true);

// submit payment
op.submit(function (err, res) {
    if(err) { console.log(err); return; }
    console.log(res);
});

查询支付选择

在井通系统中进行支付时,用户不仅可以支付自己拥有的资源,也可以选择支付自己账号中没有的资源。

当用户支付自己账号中没有的资源时,需要提交支付选择查询并选择相应支付选择。支付选择这里是指一种用户通 兑换另一种用户通的寻径方法。如果井通系统中存在相应的资源挂单,则井通系统会自动使用系统中的挂单来计算支付选择。 两种不同的用户通之间可以有多种支付选择。

例如:

A要支付B 100USD,但A只有 1000RMB,系统中同时存在多个USD和RMB之间的挂单。 账号M挂单要用100USD交换700RMB,账号N挂单挂单要用200USD交换1500RMB,那么存在两条支付选择如下:

A 700RMB -> M (挂单100USD 换 700 RMB)-> B 100USD。

A 750RMB -> N (挂单200USD 换 1500 RMB)-> B 100USD。

井通系统可以计算出所有的支付选择,然后用户使用选择好的选择进行支付。 查询支付选择方法的输入参数为接受方和用户通的种类,以及数量。 查询选择的结果为一个Choices数组,里面每个单位为所需用户通的金额(用户通符号,发行方和价值)以及相应的选择值(KEY), 格式如下:

{
    "choice": {
        "currency": "USD",
        "issuer": "jpidrAsPWDTTHhbBf9BCn5suWHQJqhynVi",
        "value": "0.001"
    },
    "key": "f53b09afcf9e1758a7b647f2f738c86426cabfc1"
}

Java Example

// construct source wallet
Wallet wallet1 = new Wallet("snqFcH......pQYzxEEbW");

// prepare payment choice amount
Amount amt = new Amount();
amt.setIssuer("jBciDE8......75AMKHEbBLS");
amt.setCurrency("USD");
amt.setValue(100);

// query payment choices
ChoiceCollection choices = wallet1.getChoices("jHb9CJA......6DkukG4bwdtyTh",amt);

Python Example

# construct source wallet
wallet1 = Wallet("shVC2gdG......gijqk4EsuqDF");

# prepare payment choice amount
amt = Amount(10, "CNY", test_issuer);

# query payment choices
r = wallet1.getChoices("jHb9CJA......6DkukG4bwdtyTh", amt);

PHP Example

// construct source wallet
$wallet1 = new Wallet('snwjtucx9......MbVz8hFiK9');

// prepare payment choice amount
$amount = new ['currency'] = 'USD';
$amount['value'] = '100';
$amount['issuer'] = 'jBciDE8Q3uJjf1......S';

// query payment choices
$ret = $wallet1->getChoices('jHb9CJAWyB......ukG4bwdtyTh', $amount);

Node.JS Example

// construct source wallet
var Wallet = JingtumSDK.Wallet;
var Amount = JingtumSDK.Amount;

var wallet1 = new Wallet('shNK......y5W5kK');

// prepare payment choice amount
var amt = new Amount('0.01', 'CNY', 'jMcCACc......M5FCk7tT');

// query payment choices
wallet1.getChoices('jD2RbZEp......sAhRYbpZ', amt, function(err, data) {
    if(err) console.log(err);
    else console.log(data);
});

按支付选择支付

按支付选择,即在支付的时候需指定用户使用的支付选择。 这一功能需要和查询支付选择结合使用,用户在查询到支付选择之后,可以选择对于用户最优的选择进行支付。 同时,用户可以指定支付选择最大可以使用的支付额度,因为市场每时每刻都在变化,支付选择也是动态的在变化。

Java Example

// construct source wallet
Wallet wallet1 = new Wallet("snqFcH......pQYzxEEbW");

// prepare payment choice amount
Amount amt = new Amount();
amt.setIssuer("jBciDE8......75AMKHEbBLS");
amt.setCurrency("USD");
amt.setValue(100);

// query payment choices
PaymentChoiceCollection choices = wallet1.getChoices("jHb9CJA......6DkukG4bwdtyTh", amt);

if (choices.getData().size() > 0) {
    // use the first choice
    PaymentChoice choice1 = choices.getData.get(0);

    // prepare payment operation
    PaymentOperation op = new PaymentOperation(wallet1);
    op.setDestAddress("jHb9CJAWyB......ukG4bwdtyTh");
    op.setChoice(choice1);
    op.setClientId("20611171957");
    op.setValidate(true);

    // submit payment
    op.submit(new PaymentListener() {
        @override
        public void onComplete(result) {
            // process result
        };
   });
}

Python Example

# construct source wallet
wallet1 = Wallet("shVC2gdG......gijqk4EsuqDF");

# prepare payment choice amount
amt = Amount(10, "CNY", test_issuer);

# query payment choices
r = wallet1.getChoices("jHb9CJA......6DkukG4bwdtyTh", amt);

if (count(r) > 0) {
    # use first choice
    choice1 = r[0]["key"];

    # prepare payment operation
    op = PaymentOperation(wallet1);
    op.setDestAddress('jHb9CJAWyB......ukG4bwdtyTh');
    op.setChoice(choice1);
    op.setValidate(True);
    op.setClientId("JT%d"%(int(time.time() * 1000)));

    # submit payment
    ret = op.submit(callback=wallet1.payment_callback);
}

PHP Example

// construct source wallet
$wallet1 = new Wallet('snwjtucx9......MbVz8hFiK9');

// prepare payment choice amount
$amount = new ['currency'] = 'USD';
$amount['value'] = '100';
$amount['issuer'] = 'jBciDE8Q3uJjf1......S';

// query payment choices
$ret = $wallet1->getChoices('jHb9CJAWyB......ukG4bwdtyTh', $amount);

if (count($ret) > 0) {
    // use first choice
    $choice = $res[0]['key'];

    // prepare payment operation
    $op = new PaymentOperation($wallet1);
    $op->setDestAddress($dest_address);
    $op->setChoice($choice1);
    $op->setValidate(true);

    // submit payment
    $res = $op->submit();
}

Node.JS Example

// construct source wallet
var Wallet = JingtumSDK.Wallet;
var Amount = JingtumSDK.Amount;

var wallet1 = new Wallet('shNK......y5W5kK');

// prepare payment choice amount
var amt = new Amount('0.01', 'CNY', 'jMcCACc......M5FCk7tT');

// query payment choices
wallet1.getChoices('jD2RbZEp......sAhRYbpZ', amt, function(err, data) {
    if(err) console.log(err);

    if (data.length > 0) {
        // use first choice
        var op = new PaymentOperation(wallet1);
        op.setChoice(ret[0]['key']);
        op.setDestAddress(dest_address);
        op.setClientId('20611171957');
        op.setValidate(true);

        // submit payment
        op.submit(function(err2, data2) {
            // process result
        });

    }
});

查询支付历史

当井通账号的支付交易完成后,所有的记录都存储在井通区块链上。 用户可以查询账号的支付历史,包括收款方,时间,通的种类和数量。 用户即可以通过交易完成后的HASH值来查询单一交易的情况,也可以根据条件来过滤所查询的支付历史。 参数包括支付方地址,对方地址,是否移除失败的支付历史,支付方向,返回的每页数据量、返回第几页的数据。 返回的结果信息里面的每个对象的字段解释信息请见数据格式的说明部分。 请注意如果不设置选项的话,默认返回的支付历史是第一页的10条数据。

参数类型说明如下:

参数 类型 说明
source_account String 支付方地址
destination_account String 支付接收方地
results_per_page Integer 返回的每页数据量,默认每页10项
page Integer 返回第几页的数据,从第1页开始

Java Example

// construct source wallet
Wallet wallet1 = new Wallet("snqFcH......pQYzxEEbW");

// get one payment
Payment payment = wallet1.getPayment("D1B87A3E46792......730DA0564ACC7");

// get payment history
PaymentCollection pc = wallet1.getPaymentList();

// query by options
Options options = {"destination_account": "jp53tPyrQL......UXUDucnwVk", "page": "1"};
PaymentCollection pc = wallet1.getPaymentList(options);

Python Example

# construct source wallet
wallet1 = Wallet("shVC2gdG......gijqk4EsuqDF");

# get one payment
r = wallet1.getPayment('D1B87A3E46792......730DA0564ACC7');

# get payment history
r = wallet1.getPaymentList();

# query by options
options = {"destination_account": "jp53tPyrQL......UXUDucnwVk", "page": "1"}
r = wallet1.getPaymentList (options);

PHP Example

// construct source wallet
$wallet1 = new Wallet('snwjtucx9......MbVz8hFiK9');

// get one payment
$res = $wallet1->getPayment('D1B87A3E46792......730DA0564ACC7');

// get payment history
$res = $wallet1->getPaymentList();

// query by options
$options['source_account'] = "jp53tPyrQL......UXUDucnwVk";
$options['results_per_page'] = 15;
$options['page'] = 1;
$res = $wallet1->getPaymentList($options);

Node.JS Example

var Wallet = require('jingtum-sdk').Wallet;
// construct source wallet
$wallet1 = new Wallet('snwjtucx9......MbVz8hFiK9');

// get one payment
var hash_id = 'D1B87A3E46792......730DA0564ACC7';
wallet1.getPayment(hash_id, function(err, data) {
    if(err) console.log(err);
    else console.log(data);
});

// get payment history
wallet1.getPaymentList(function(err, data) {
    if(err) console.log(err);
    else console.log(data);
});

// query by options
var options = {
    source_account:'jp53tPyrQL......UXUDucnwVk',
    destination_account:'j4PqT7......T8jrXgBhm1L4BpW',
    results_per_page:2
};
wallet1.getPaymentList(options, function(err, data) {
    if(err) console.log(err);
    else console.log(data);
});