laravellaravel-5paypalpaypal-sandboxomnipay

Omnipay Paypal Express Checkout Error: Security header is not valid


Whenever setTestMode() method is used, the error "Security header is not valid" pops up.

But if I remove setTestMode() and just keep the setUsername(), setPassword(), and setSignature() methods, it goes through and redirects straight to PayPal (Live Paypal).

So AFAIK the problem should lie in how I'm using setTestMode and not about incorrect API creds as most "Security header is not valid" errors are about.

I am currently using Laravel 5.8 with Omnipay/PayPal using PayPal Express Checkout

Here are the files that were used

Paypal.php

public function gateway()
{
    $gateway = Omnipay::create('PayPal_Express');

    $gateway->setUsername(config('services.paypal.username'));
    $gateway->setPassword(config('services.paypal.password'));
    $gateway->setSignature(config('services.paypal.signature'));
    $gateway->setTestMode(config('services.paypal.sandbox'));
    // $gateway->setTestMode(true);

    return $gateway;
}

public function purchase(array $parameters)
{
    $response = $this->gateway()
        ->purchase($parameters)
        ->send();

    return $response;
}

PaypalController.php

public function checkout($order_id)
{
    $order = Order::findOrFail(decrypt($order_id));

    $paypal = new PayPal;

    $response = $paypal->purchase([
        'amount' => $paypal->formatAmount($order->amount),
        'transactionId' => $order->transaction_id,
        'currency' => 'PHP',
        'cancelUrl' => $paypal->getCancelUrl($order),
        'returnUrl' => $paypal->getReturnUrl($order),
        'notifyUrl' => $paypal->getNotifyUrl($order),
    ]);

    if ($response->isRedirect()) {
        $response->redirect();
    }

    return redirect()->back()->with([
            'message' => $response->getMessage(),                
    ]);
}

Here are the contents of the $response

ExpressAuthorizeResponse {#1098 ▼
  #liveCheckoutEndpoint: "https://www.paypal.com/cgi-bin/webscr"
  #testCheckoutEndpoint: "https://www.sandbox.paypal.com/cgi-bin/webscr"
  #request: ExpressAuthorizeRequest {#1095 ▼
    #liveEndpoint: "https://api-3t.paypal.com/nvp"
    #testEndpoint: "https://api-3t.sandbox.paypal.com/nvp"
    #negativeAmountAllowed: true
    #parameters: ParameterBag {#1097 ▶}
    #httpClient: Client {#1063 ▶}
    #httpRequest: Request {#1086 ▶}
    #response: ExpressAuthorizeResponse {#1098}
    #currencies: ISOCurrencies {#1096}
    #zeroAmountAllowed: true
  }
  #data: array:9 [▼
    "TIMESTAMP" => "2020-02-03T11:04:45Z"
    "CORRELATIONID" => "c8d066c9b5ccd"
    "ACK" => "Failure"
    "VERSION" => "119.0"
    "BUILD" => "54118205"
    "L_ERRORCODE0" => "10002"
    "L_SHORTMESSAGE0" => "Security error"
    "L_LONGMESSAGE0" => "Security header is not valid"
    "L_SEVERITYCODE0" => "Error"
  ]
}

---EDIT---

Just made a new Sandbox Business Account and used that one's NVP API Creds and then it worked! The old account's problem was probably it's email that I edited because that was the only difference between the old and new one.


Solution

  • The live and test/sandbox environments are completely separate, and so require separate credentials.

    For the PayPal Sandbox (test mode), you need an API Username, Password, and Signature from a sandbox PayPal Business account, via https://www.paypal.com/signin?intent=developer&returnUri=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Faccounts%2F


    The 10002 "Security Header is not Valid" always indicates your credentials are not valid, i.e. there is a problem with the Username/Password/Signature or you are using live ones in sandbox mode, or vice-versa