I'm currently implementing BitPay as an additional payment method in our website, using PHP.
I've been following the provided documentation:
https://developer.bitpay.com/reference/php-full-sdk-getting-started#setup
https://developer.bitpay.com/reference/php-full-sdk-create-an-invoice
https://developer.bitpay.com/docs/signed-request-flow
So first I start by creating the private key:
$privateKey = PrivateKey::create(<FILENAME>)->generate();
$storageEngine = new EncryptedFilesystemStorage(<PASS>);
$storageEngine->persist($privateKey);
$privateKey = $storageEngine->load(<FILENAME>);
$publicKey = $privateKey->getPublicKey();
As I understood the SIN is the hash of the public key:
$sin = $publicKey->getSin()->__toString();
We'll be using the PoS facade, which should be sufficient for basic invoice creation, according to their documentation:
$resourceUrl = 'https://test.bitpay.com/tokens';
$facade = 'pos';
$postData = json_encode([
'id' => $sin,
'label' => 'Token',
'facade' => $facade
]);
$curlCli = curl_init($resourceUrl);
curl_setopt($curlCli, CURLOPT_HTTPHEADER, [
'x-accept-version: 2.0.0',
'Content-Type: application/json',
'x-identity' => $publicKey->__toString(),
'x-signature' => $privateKey->sign($resourceUrl . $postData),
]);
curl_setopt($curlCli, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($curlCli, CURLOPT_POSTFIELDS, stripslashes($postData));
curl_setopt($curlCli, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curlCli);
$resultData = json_decode($result, TRUE);
curl_close($curlCli);
$token = $resultData['data'][0]['token'];
$bitpay = new PosClient($token, 'test');
$invoice = new Invoice(<AMOUNT>, Currency::USD);
$invoice->setToken($token);
$invoice->setToken($token);
$invoice->setFullNotifications(true);
$invoice->setExtendedNotifications(true);
$client = new Buyer();
$client->setName(<NAME>);
$client->setEmail(<MAIL>);
$client->setAddress1(<ADDRESS>);
$client->setCountry(<COUNTRY>);
$client->setLocality(<CITY>);
$client->setNotify(true);
$invoice->setBuyer($client);
try {
$new_invoice = $bitpay->createInvoice($invoice, Facade::POS, false);
} catch (\Exception $e) {
print_r($e->getMessage());
}
The private key is created and the call to their API is successful. The response is the same as expected and the token is obtained:
{"data":
[{"policies":
[{"policy":"id",
"method":"inactive",
"params":["Tf3wXWuwfT1TmenHF21P1nYZ7BeyrYNdiwo"]
}],
"token":"<TOKEN>,
"facade":"pos",
"label":"Token",
"dateCreated":1696926578101,
"pairingExpiration":1697012978101,
"pairingCode":"<CODE>"
}]
}
However the problem that I'm experiencing, is that when I try to create the invoice in the final step, I'm hitting the below exception:
"BITPAY-INVOICE-CREATE: Failed to create invoice-> failed to serialize Invoice object : failed to retrieve HTTP response body : Token is disabled"
It's either that, or I get Token is invalid. Is there something that I'm missing?
Tried using the merchant/payout instead of POS as well, using the create with file option:
Client::createWithFile();
The result is the same. The .env file is the json template mentioned here: https://developer.bitpay.com/docs/signed-request-flow#overview