omnipay-coinbase
omnipay-coinbase copied to clipboard
Error "Unable to parse response body into JSON: 4" when sending request
Hello, I think I'm doing everything right:
$gateway = Omnipay::create("Coinbase");
$gateway->initialize(['apiKey' => 'my_api_v2_key_with_all_perm', 'secret' => 'my_api_secret', 'accountId' => 'my_acc_id']);
$transaction = $gateway->purchase(['amount' => 10, 'currency' => 'USD', 'description' => 'something']);
$response = $transaction->send();
but getting an error message on send():
Unableto parse response body into JSON: 4
Whats going on? I've managed to check that this error is caused by empty (NULL
) json returned by guzzle. But what causes it?
+1, I also ran into this in the InvoicePlane implementation.
https://community.invoiceplane.com/t/topic/4572/6?u=epec
@konrad-ch did you ever get to the bottom of this? I'm having the same issue
@Moorst If i remember correctly I managed to fix the error, but moved to another btc processor since then and forgot to make a clean patch and share. Please check these files I digged out, maybe you can make a fix based on that:
AbstractRequest.php:
<?php
namespace Omnipay\Coinbase\Message;
/**
* Coinbase Abstract Request
*
* @method \Omnipay\Coinbase\Message\Response send()
*/
abstract class AbstractRequest extends \Omnipay\Common\Message\AbstractRequest
{
const API_VERSION = 'v2';
const API_VERSION_STRICT = '2018-03-05';
protected $liveEndpoint = 'https://api.coinbase.com';
protected $testEndpoint = 'https://api.sandbox.coinbase.com';
public function getApiKey()
{
return $this->getParameter('apiKey');
}
public function setApiKey($value)
{
return $this->setParameter('apiKey', $value);
}
public function getSecret()
{
return $this->getParameter('secret');
}
public function setSecret($value)
{
return $this->setParameter('secret', $value);
}
public function getAccountId()
{
return $this->getParameter('accountId');
}
public function setAccountId($value)
{
return $this->setParameter('accountId', $value);
}
public function sendRequest($method, $action, $data = null)
{
// don't throw exceptions for 4xx errors
$this->httpClient->getEventDispatcher()->addListener(
'request.error',
function ($event) {
if ($event['response']->isClientError()) {
$event->stopPropagation();
}
}
);
//$nonce = $this->generateNonce();
$timestamp = time();
$url = $this->getEndpoint().$action;
//$body = $data ? http_build_query($data) : null;
$httpRequest = $this->httpClient->createRequest($method, $url, null, $data);
$httpRequest->setHeader('Content-Type', 'application/json');
$httpRequest->setHeader('CB-ACCESS-KEY', $this->getApiKey());
$httpRequest->setHeader('CB-ACCESS-SIGN', $this->generateSignature($method, $url, $data, $timestamp));
$httpRequest->setHeader('CB-ACCESS-TIMESTAMP', $timestamp);
$httpRequest->setHeader('CB-VERSION', self::API_VERSION_STRICT);
return $httpRequest->send();
}
public function generateNonce()
{
return sprintf('%0.0f', round(microtime(true) * 1000000));
}
public function generateSignature($method, $url, $body, $timestamp)
{
$message = $timestamp.strtoupper($method).parse_url($url, PHP_URL_PATH).$body;
return hash_hmac('sha256', $message, $this->getSecret());
}
/*
public function generateSignature($url, $body, $nonce)
{
$message = $nonce.$url.$body;
return hash_hmac('sha256', $message, $this->getSecret());
}
*/
protected function getEndpoint()
{
$base = $this->getTestMode() ? $this->testEndpoint : $this->liveEndpoint;
return $base . '/' . self::API_VERSION;
}
}
PurchaseRequest.php
<?php
namespace Omnipay\Coinbase\Message;
/**
* Coinbase Purchase Request
*
* @method \Omnipay\Coinbase\Message\PurchaseResponse send()
*/
class PurchaseRequest extends AbstractRequest
{
public function getData()
{
$this->validate('amount', 'currency', 'description');
$data = [
"amount" => $this->getAmount(),
"currency" => $this->getCurrency(),
"name" => $this->getDescription()
];
/*
$data = array();
$data['account_id'] = $this->getAccountId() ?: null;
$data['button'] = array();
$data['button']['name'] = $this->getDescription();
$data['button']['price_string'] = $this->getAmount();
$data['button']['price_currency_iso'] = $this->getCurrency();
$data['button']['success_url'] = $this->getReturnUrl();
$data['button']['cancel_url'] = $this->getCancelUrl();
$data['button']['callback_url'] = $this->getNotifyUrl();
*/
return $data;
}
public function sendData($data)
{
//$httpResponse = $this->sendRequest('POST', '/buttons', $data);
$httpResponse = $this->sendRequest('POST', '/checkouts', json_encode($data));
return $this->response = new PurchaseResponse($this, $httpResponse->json());
}
}