Skip to content
Advertisement

How to handle multiple environments: dev, staging and production with paypal webhooks?

I would like to have three environments, where I can test and use paypal webhooks. My current approach is to create new webhook for every environment in paypal developer portal and when request arrives check if it is for that environment. How does paypal handle multiple webhook urls and what status code should be returned if environment is not correct?

Advertisement

Answer

Create a Class like below to keep in the beginning of your application. Let it initialize once.

class App {
    private static $env_status = null;
    private static $paypal_settings = [];

    const ENV_PRODUCTION = "production";
    const ENV_STAGING = "staging";
    const ENV_DEV = "development";

    public static function init() {
        // Set environment status.  
        // You can also parse domain name and depending on your domain, you can set the environment status.
        self::$env_status = getenv("ENV_STATUS");   // getenv() Gets from Environment variable. You'll need set clear_env = no in php config for this to work.

        switch(self::$env_status) {
            case App::ENV_PRODUCTION:
                self::$paypal_settings = [
                    "mode" => "live"
                    "clientID" => "PRODUCTION_CLIENT_ID" ,
                    "secret" => "PRODUCTION_SECRET" ,
                    "currency" => "USD",
                    "webhook" => "https://example.com/live_webhook_endpoint"
                ];

                break;

            case App::ENV_STAGING:
                self::$paypal_settings = [
                    "mode"=> "sandbox"
                    "clientID"=> "STAGING_CLIENT_ID" ,
                    "secret"=> "STAGING_SECRET" ,
                    "currency"=> "USD",
                    "webhook" => "https://example.com/staging_webhook_endpoint"
                ];

                break;

            default:
                // ENV_DEV settings
                self::$paypal_settings = [
                    "mode"=> "sandbox"
                    "clientID"=> "DEVELOPMENT_CLIENT_ID" ,
                    "secret"=> "DEVELOPMENT_SECRET" ,
                    "currency"=> "USD",
                    "webhook" => "https://example.com/development_webhook_endpoint"
                ];
                break;
        }
    }

    public static function env_status() {
        return self::$env_status;
    }

    public static function paypal_settings() {
        return self::$paypal_settings;
    }

    // You can also create seprate function if you just want webhook URL. 
    // You can define in different variable also if that's the case.
    public static function paypal_webhook_url() {
        return self::$paypal_settings['webhook'];
    }

} App::init();

Then whenever you want to get paypal settings you can call it from anywhere in your Application.

$paypay_settings = App::paypal_settings();

OR if you need just paypal webhook URL

$paypal_webhook_url = App::paypal_webhook_url();

This way you don’t have to keep any conditions in other parts of your code. All the conditions will go in a single place, which will be easier to update later.

How does paypal handle multiple webhook urls.

You will need to hit PayPal Sandbox URL to hit for staging/development environment.

What status code should be returned if environment is not correct?

HTTP 400. Since it will be an invalid request.

Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400

The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement