This is a follow up question to this post but my question is more programming related so I'm hoping this is the right place to post it.
I too am trying to use BTC Pay Server as a wallet. Thera are two problems:
As described in the article, you have to specify an amount when creating an invoice.
It has a security feature that basically results in you not being able to re-use deposit addresses.
The workaround for problem 1 is to set the invoice amount to 0.000001 BTC. So low that the client will always overpay. That works for me to.
But my problem is that address must not expire ever. I checked the code:
Here you can see the Invoice object.
Here you can see the code in use.
It looks like I might be able to use this:
public function setExpirationTime($expirationTime)
{
if (is_a($expirationTime, 'DateTime')) {
$this->expirationTime = $expirationTime;
} else if (is_numeric($expirationTime)) {
$expirationDateTime = new \DateTime('', new \DateTimeZone("UTC"));
$expirationDateTime->setTimestamp($expirationTime);
$this->expirationTime = $expirationDateTime;
}
return $this;
}
And set the expiration time to the year 3000. So my questions are:
Will BTC Pay server ditch my address if I attempt to use this to make it never expire?
Will I still receive the funds if a user sends to an expired address/
Or is there perhaps a better way to get BTC Pay server to act as a wallet as I want it to?
Thanks!
Will BTC Pay server ditch my address if I attempt to use this to
make it never expire?
Actually, you may encounter the year 2038 problem if the type for expirationTime is DateTime. If that really is the case, it will be set a negative value when you try to pass a value larger than 2038. It is unclear what will happen next.
If the system the code is running on is 64bit, then the Y2038 problem does not apply.
Will I still receive the funds if a user sends
to an expired address
https://docs.btcpayserver.org/FAQ/FAQ-Stores/#payment-invalid-if-transactions-fails-to-confirm-minutes-after-invoice-expiration
If the customer pays the invoice, but it fails to get the defined
number of confirmations within the set period, it is marked as
"invalid." The merchant can then decide whether to accept the invoice
afterward manually or decline it and require additional payment from
the customer. This is an additional protection mechanism against the
volatility
So not exactly - some work is required on your part to accept it, if it expires.
Or is there perhaps a better way to get BTC
Pay server to act as a wallet as I want it to?
Instead of setting it to the year 3000, why don't you just set the invoice a year ahead at a time ?
Related
I am new to stellar so please bear with my question if it sounds too basic.
So, using the stellar laboratory, I created two accounts lets name 1 and 2. I funded the 1st account with test-net coins using friend-bot and left the 2nd account empty. Now as I understand that an account to be active on stellar network, it should have a minimum balance of about 1XLM. So using the transaction builder, I tried to perform a Payment Operation by trying to transfer 2XLM to the 2nd account. However I recieved the following response :
{
"type": "https://stellar.org/horizon-errors/transaction_failed",
"title": "Transaction Failed",
"status": 400,
"detail": "The transaction failed when submitted to the stellar network. The `extras.result_codes` field on this response contains further details. Descriptions of each code can be found at: https://www.stellar.org/developers/learn/concepts/list-of-operations.html",
"extras": {
"envelope_xdr": "AAAAAKNyr+6/r2REKzMV3sOL4jztg1HSdqlQhmthUU41BjPdAAAAZAAEmkQAAAADAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAmWhqbEZTUrZWFtvR1HU7VUW0pp3BwN4E9h4iQwvMr9kAAAAAAAAAAAExLQAAAAAAAAAAATUGM90AAABAHvtdpnjhq3usHFphQ/4naDHbKVhu+QqD8UFSavo/qlGo7Yiz/dLI3lQ0fmfa37uvwXWsYAn8mObDkrTjofc3Aw==",
"result_codes": {
"transaction": "tx_failed",
"operations": [
"op_no_destination"
]
},
"result_xdr": "AAAAAAAAAGT/////AAAAAQAAAAAAAAAB////+wAAAAA="
}
}
So can someone tell me which operation I need to use to send XLM to an un-initialised address so I can activate it, not by using friendbot.
First, you need to execute Create Account from the Transaction Builder.
Only then you can transfer funds to this address.
I think it's because the Stellar laboratory is not set up for this exact use case. It is more for getting a general feel of the basics. In order to create an account this way using an SDK and communicating with horizon you would have to both create the account and fund it in a single transaction, and therefore you would have to input the source account's secret key.
In the Stellar lab's account creation tab there is no way to input a source address its secret key (or at least I didn't see one).
So in your example, your first account is created and funded by the testbot. However, when you create the second account and try to send a payment to it from the first account, the reason it fails is because the second account is not yet a valid account as it has not been funded yet. Kind of a chicken and egg problem.
The good news is you can definitely do this using the SDK, but I haven't found a way to do it using the lab.
This from stellar.org about building transactions:
https://www.stellar.org/developers/js-stellar-base/reference/building-transactions.html
TransactionBuilder
The TransactionBuilder class is used to construct
new transactions. TransactionBuilder is given an account that is used
as transaction’s “source account”. The transaction will use the
current sequence number of the given Account object as its sequence
number and increments the given account’s sequence number when build()
is called on the TransactionBuilder.
Operations can be added to the transaction calling
addOperation(operation) for each operation you wish to add to the
transaction. See operation.js for a list of possible operations you
can add. addOperation(operation) returns the current
TransactionBuilder object so you can chain multiple calls.
After adding the desired operations, call the build() method on the
TransactionBuilder. This will return a fully constructed Transaction.
The returned transaction will contain the sequence number of the
source account. This transaction is unsigned. You must sign it before
it will be accepted by the Stellar network.
# This is the relevant code
StellarSdk.Network.useTestNetwork();
// StellarBase.Network.usePublicNetwork(); if this transaction is for the public network
// Create an Account object from an address and sequence number.
var account=new StellarBase.Account("GD6WU64OEP5C4LRBH6NK3MHYIA2ADN6K6II6EXPNVUR3ERBXT4AN4ACD","2319149195853854");
var transaction = new StellarBase.TransactionBuilder(account, {
fee: StellarBase.BASE_FEE
})
// add a payment operation to the transaction
.addOperation(StellarBase.Operation.payment({
destination: "GASOCNHNNLYFNMDJYQ3XFMI7BYHIOCFW3GJEOWRPEGK2TDPGTG2E5EDW",
asset: StellarBase.Asset.native(),
amount: "100.50" // 100.50 XLM
}))
// add a set options operation to the transaction
.addOperation(StellarBase.Operation.setOptions({
signer: {
ed25519PublicKey: secondAccountAddress,
weight: 1
}
}))
// mark this transaction as valid only for the next 30 seconds
.setTimeout(30)
.build();
# Note that it is adding different operations to a single transaction.
I entered this as an issue on the PayPal-PHP-SDK github but it's rather time sensitive at this point.
Our goal is a subscription service that monthly charges users a value they select for each content update during that month. A $1 subscriber would pay $8 if there were 8 updates, for example.
Our implementation so far (which is already live with a number of subscribers) is using the PayPal-PHP-SDK / REST API to create a Billing Plan for each subscriber with a payment definition set to an amount calculated to be the maximum potential monthly charge. I then expected to be able to use Agreement->setBalance() to lower the value to the actual intended charge and then Agreement->billBalance() to process the payment.
Unfortunately due to time pressures we launched without verifying this was a viable implementation, and I've discovered that those functions are only for unpaid/delinquent balances. The start_date on our plans is April 1, and we'll have had 4 content releases but we're set to charge our subscribers for the maximum possible 9 updates.
I've tried a variety of Agreement->update() and Plan->update() calls to change the monthly value, along the lines of:
$Patch = new PayPal\Api\Patch();
$Patch->setOp("replace")
->setPath("/payment_definitions/0/amount/value")
->setValue($patch_value);
$PatchRequest = new PayPal\Api\PatchRequest();
$PatchRequest->addPatch($Patch);
$Plan = PayPal\Api\Plan::get($plan_id, $apiContext);
$Plan->update($PatchRequest, $apiContext);
which returns an exception with "validation_error: Invalid Path provided". Attempts to json encode the data path, up to and including the entire Plan object with $Patch->setPath("/") instead give an exception with "MALFORMED_REQUEST - Incoming JSON request does not map to API request". I suspect most values cannot be updated on an executed agreement or activated plan.
However, I see through the merchant account's website that the monthly value can be manually updated, so I hold out hope that I'm simply going about my API requests the wrong way.
I've also tried creating a Payment object with Transaction->setPurchaseUnitReferenceId($AgreementId) since I'd read something about reference transactions being a potential solution, but I'm getting the same malformed request error:
$Item = new PayPal\Api\Item();
$Item->setCategory('DIGITAL')
->setPrice($pledge_value)
->setDescription($update_name);
$ItemList = new PayPal\Api\ItemList();
$ItemList->addItem($Item);
$Amount = new PayPal\Api\Amount();
$Amount->setCurrency('USD')
->setTotal($pledge_value);
$Transaction = new PayPal\Api\Transaction();
$Transaction->setPurchaseUnitReferenceId($AgreementId)
->setDescription($update_name)
->setAmount($Amount)
->setItemList($ItemList)
->setNotifyUrl($notify_url);
$Payer = new PayPal\Api\Payer();
$Payer->setPaymentMethod('paypal');
$RedirectUrls = new PayPal\Api\RedirectUrls();
$RedirectUrls->setReturnUrl($return_url)
->setCancelUrl($cancel_url);
$Payment = new PayPal\Api\Payment();
$Payment->setIntent('sale')
->setPayer($Payer)
->setRedirectUrls($RedirectUrls)
->addTransaction($Transaction);
$Payment->create($apiContext);
So is there a way to fix our current implementation and plans/agreements? Failing that, is there a REST API solution that I should have used / can try to migrate to? I'd like to avoid Classic API if possible.
The first result from Google gave me an answer from 2012 so I wondered if there was a better one than 'use armoury' now?
It's fine if I have to decode the raw transactions, I would be grateful if someone could take me through the steps.
Thanks in advance :)
I'll answer my own question,
It was unbelievably easy.
(from the debug console or command line)
listunspent
produces a/the list of unspent outputs at your disposal.
Make a note of the 'txid', 'vout' and 'scriptPubKey' of each output you wish to use.
Use the 'createrawtransaction' command followed by a list of dictionaries containing the txid's and vout's of the inputs you chose earlier followed by the addresses you wish to send them to (the send to addresses are in a single dictionary, not a list of dictionaries).
createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,...}
If you don't want to send the outputs in total (you want some change for yourself) you will need to include an address that you control in your sending dictionary (from your wallet or somewhere else) since outputs cannot be partially spent, sorry.
To pay the mining fee simply leave some of the total output amount unaccounted for and bitcoin will use it as the mining fee by default (fee is 0.0001 at time of writing).
If all went well you should be given a hex string.
Use the 'signrawtransaction' command to check there are no errors by passing in your new hex string followed by a list of dictionaries with the txid's, vout's and scriptPubKeys we got at the very beginning of all this.
signrawtransaction <hex string> [{"txid":txid,"vout":n,"scriptPubKey":hex},...]
note: in newer versions of bitcoin the list of dictionaries is not required
If you got a new hex with "complete" : true after it then all went well and you can now use the 'sendrawtransaction' command followed by the even newer hex you were just given to broadcast your newly created transaction into the bitcoin network.
sendrawtransaction <new hex string>
If you managed to sign it successfully but get a "code":-22,"message":"TX rejected" error please see the footnote below.
Notice it only took four commands in total:
*get (listunspent)
*create (createrawtransaction)
*sign (signrawtransaction)
*send (sendrawtransaction)
Easy :)
FOOTNOTE:
Be aware if you designate an unusually large fee like 0.5btc (I tried this on the testnet) the network will reject your transaction when you try to broadcast it because it thinks you've made a mistake which I discovered whilst I was experimenting.
(This is also the case if you are trying to spend more BTC than you have available.)
In the end I set the fee to 0.001 and it worked fine, here is a link to my question regarding this situation.
Another possibility is with Electrum. Under the Addresses tab right-click on one with non-zero balance and select 'Spend from'.
You have to click View > Show Addresses if you do not have the Addresses tab.
from where you wanna send your BTC. All you need to fill the withdrawal address of bitcoins. You may send your BTC to Bitfinex with the same process:
Fill withdraw address
Fill amount to be sent.
Verify your payment.
Done.
For some deliveries I require a signature which is an extra charge. I would like to know what that extra charge is, using the rate request API. I'd like to know if this is the place to get that value or if there is some other way.
In the documentation, I only see the SignatureOption element in the explanation for the RateReplyDetails, but nothing for how to send it to them in the RateRequest. The replies always say "SERVICE_DEFAULT" for the SignatureOption with a value of zero. I would like the reply to come back with, for example, INDIRECT and some dollar amount. Other options for this are ADULT, DIRECT, NO_SIGNATURE_REQUIRED, etc.
Below you can see where I tried putting the element under the RequestedShipment element. But that causes the reply to be an "invalid element" error. I tried it in various places in the RateRequest to no avail.
<ns:RateRequest xmlns:ns="http://fedex.com/ws/rate/v7" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns:WebAuthenticationDetail>
<ns:UserCredential>
<ns:Key>00000</ns:Key>
<ns:Password>00000</ns:Password>
</ns:UserCredential>
</ns:WebAuthenticationDetail>
<ns:ClientDetail>
<ns:AccountNumber>00000</ns:AccountNumber>
<ns:MeterNumber>00000</ns:MeterNumber>
</ns:ClientDetail>
<ns:Version>
<ns:ServiceId>crs</ns:ServiceId>
<ns:Major>7</ns:Major>
<ns:Intermediate>0</ns:Intermediate>
<ns:Minor>0</ns:Minor>
</ns:Version>
<ns:RequestedShipment>
<ns:SignatureOption>INDIRECT</ns:SignatureOption>
<ns:ShipTimestamp>#DateFormat(Now(),'yyyy-mm-dd')#T#TimeFormat(Now(),'hh:mm:ss')#</ns:ShipTimestamp>
<ns:DropoffType>REGULAR_PICKUP</ns:DropoffType>
<ns:PackagingType>YOUR_PACKAGING</ns:PackagingType>
When using more recent versions of the API you need to set the option inside of RequestedPackageLineItems. Only send the element when you've got an actual signature option selection.
<RequestedPackageLineItems>
… dim, weight, etc…
<SpecialServicesRequested>
<SpecialServiceTypes>SIGNATURE_OPTION</SpecialServiceTypes>
<SignatureOptionDetail>
<OptionType>DIRECT|INDIRECT|ADULT|NO_SIGNATURE_REQUIRED</OptionType>
</SignatureOptionDetail>
</SpecialServicesRequested>
</RequestedPackageLineItems>
While adnyknas answer is correct, regarding the place you should put it in your XML, please note that the Signature service request only works in the USA:
This is info I got from FedEX tech support:
Signature Require (SR) services are unavailable in most countries. It is for FedEx Express U.S. package services and FedEx Ground U.S. services only in U.S.A. Refer to below restriction from http://www.fedex.com/us/2014rates/surcharges-and-fees.html
I have the following working in Sandbox
*Return without Autoreturn, no PDT;
*Return with Autoreturn, with PDT;
*IPN works properly
What I want to use is Autoreturn without PDT but when that is set Autoreturn sends no Get or Post variables. I've also checked the various other posts on this subject and rm=2 is set. Any help appreciated
$API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
$PAYPAL_URL = "https://www.sandbox.paypal.com/cgi-bin/webscr?";
$newpost['business']='xxxxxxxxxx';
$newpost['cancel_return']='http://localhost/cz/subscribe.php';
$newpost['return']='https://www.xxxxxxxx/paypal/success_test.php';
$newpost['cmd']='_donations'; //donation checkout
$newpost['lc']='US';
$newpost['rm']='2';
$newpost['cbt']='Click to Set Subscriber Status';
$newpost['currency_code']='USD';
$newpost['button_subtype']='services';
$newpost['no_note']='1';
$newpost['no_shipping']='2'; //shipping address required
$newpost['tax_rate']='0.000';
$newpost['bn']='xxxxxxxx_BuyNow_WPS_US';
$newpost['amount']=$prod[1];
$newpost['item_name']=' Subscription'; //product name
After a lot of testing what I found was Paypal Sandbox as of Sep 23 2013 on non-PAYPAL account transactions autoreturns using IPN format when using CMD=_xclick, however on CMD=_donation it sits there waiting until the user clicks the return to mysite button.
*When processing a Paypal account transaction with CMD=_donation, autoreturn using IPN format returns nothing.* Using CMD=_xclick and allowing it to return in ten seconds works, as does clicking "If you are not redirected within 10 seconds, click here."
I don't know if this behavior occurs in production, however it rivals the readability of the Paypal documentation for clarity and understanding.