Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save infysumanta/8f0f78351ee397edd14649f2dcc31555 to your computer and use it in GitHub Desktop.
Save infysumanta/8f0f78351ee397edd14649f2dcc31555 to your computer and use it in GitHub Desktop.
The code snippet defines two functions. The first function, `getAuthenticationToken`, retrieves an access token for authentication using client credentials. The second function, `paymentWithCard`, handles the payment process using a credit card, including creating an order, capturing

Payment with Credit Card using PayPal API

Preview:
const PAYPAL_CLIENT_ID = process.env.PAYPAL_CLIENT_ID!!;
const PAYPAL_CLIENT_SECRET = process.env.PAYPAL_CLIENT_SECRET!!;
const PAYPAL_MODE = process.env.PAYPAL_MODE;
const SANDBOX_URL = 'https://api-m.sandbox.paypal.com';
const LIVE_URL = 'https://api-m.paypal.com';

const requestUrl = PAYPAL_MODE === 'sandbox' ? SANDBOX_URL : LIVE_URL;



/**
 * The function `getAuthenticationToken` retrieves an access token for authentication using client
 * credentials.
 * @returns The function `getAuthenticationToken` is returning the access token obtained from the
 * OAuth2 token endpoint.
 */
const getAuthenticationToken = async () => {
  const token = await axios({
    method: 'POST',
    url: `${requestUrl}/v1/oauth2/token`,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    data: {
      grant_type: 'client_credentials',
    },
    auth: {
      username: PAYPAL_CLIENT_ID,
      password: PAYPAL_CLIENT_SECRET,
    },
  });
  const accessOAuthToken = token.data.access_token;
  return accessOAuthToken;
};


/**
  * The `paymentWithCard` function handles the payment process using a credit card, including
  * creating an order, capturing the payment, and returning a success or failure response.
  * @param {ExtendAuthRequest} req - The `req` parameter is an object that represents the HTTP
  * request. It contains information such as the request body, headers, and user information.
  * @param {Response} res - The `res` parameter is the response object that is used to send the HTTP
  * response back to the client. It contains methods and properties for manipulating the response,
  * such as setting the status code, headers, and sending the response body.
  * @param {NextFunction} next - The `next` parameter is a function that is used to pass control to
  * the next middleware function in the request-response cycle. It is typically used to handle errors
  * or to move on to the next middleware function after completing a specific task.
  * @returns a JSON response with a status code and a message. If the payment is successful, it will
  * return a status code of 200 and a message of 'success'. If the payment fails, it will return a
  * status code of 404 and a message of 'Payment Failed'.
  */

export const paymentWithCard = async (
  req: ExtendAuthRequest,
  res: Response,
  next: NextFunction,
) => {
  try {
    const { order_id, cardHolderName, cardNumber, expiryDate, securityCode } =
      req.body;

    const accessOAuthToken = await getAuthenticationToken();

    const chosenPlan = {
      price: 150,
      name: '',
      description: '',
      identifier: order_id,
      noOfVideoCall: '',
    };
/* The above code is making a POST request to create an order for a checkout process. It is using the
axios library to send the request. The request is being sent to the specified URL with the necessary
headers, including an authorization token. The request body includes information about the intent of
the order (CAPTURE), the payer's name and email address, and details about the purchase units and
items. The response from the request is being stored in the `createOrder` variable. */

    const createOrder = await axios({
      method: 'POST',
      url: `${requestUrl}/v2/checkout/orders`,
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${accessOAuthToken}`,
      },
      data: {
        intent: 'CAPTURE',
        payer: {
          name: {
            given_name: req.userInfo?.firstName,
            surname: req.userInfo?.lastName,
          },
          email_address: req.userInfo?.email,
        },
        purchase_units: [
          {
            custom_id: req.userInfo?._id,
            amount: {
              currency_code: 'USD',
              value: chosenPlan?.price,
              breakdown: {
                item_total: {
                  currency_code: 'USD',
                  value: chosenPlan?.price,
                },
              },
            },
            items: [
              {
                name: chosenPlan.name,
                description: chosenPlan.description,
                sku: chosenPlan.identifier,
                unit_amount: {
                  currency_code: 'USD',
                  value: chosenPlan?.price,
                },
                quantity: chosenPlan?.noOfVideoCall,
              },
            ],
          },
        ],
      },
    });

    if (createOrder?.data?.status !== 'CREATED') {
      return res.status(404).json({
        status: 404,
        message: 'Payment Failed',
      });
    }
    /* The above code is making a POST request to capture an order using the PayPal API. It is sending
    the necessary headers and data required for the request, including the payment source details
    such as card number, expiry date, security code, and card holder name. */
    const captureOrder = await axios({
      method: 'POST',
      url: `${requestUrl}/v2/checkout/orders/${createOrder.data.id}/capture`,
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${accessOAuthToken}`,
      },
      data: {
        payment_source: {
          card: {
            number: cardNumber,
            expiry: expiryDate,
            security_code: securityCode,
            name: cardHolderName,
          },
        },
      },
    });
    if (captureOrder?.data?.status !== 'COMPLETED') {
      return res.status(404).json({
        status: 404,
        message: 'Payment Failed',
      });
    }
    return res.status(200).json({
      status: 200,
      message: 'success',
    });
  } catch (error) {
    console.log(error);
    next(error);
  }
};






/**
 * Handles the activation of a PayPal webhook.
 * @param {Request} req - The request object.
 * @param {Response} res - The response object.
 * @param {NextFunction} next - The next function.
 * @returns {Promise<void>} - A promise that resolves when the webhook is handled.
 */
export const paypalWebhookActivatedHandler = async (
  req: Request,
  res: Response,
  next: NextFunction,
) => {
  try {
   const event_type = req.body.event_type;
    const summary = req.body.summary;
    const order_id = req.body.resource.id;
    const status = req.body.resource.status;

    const webhookData = {
      event_type,
      summary,
      recurring_payment_id: subscription_id,
      status,
    };

    //perform the activity for  update the payment infoormation

    res.status(200).send({
      message: 'Webhook received successfully',
    });
  } catch (error) {
    console.error(error);
    next(error);
  }
};

/**
 * Handles the cancellation webhook from PayPal.
 * @param {Request} req - The request object.
 * @param {Response} res - The response object.
 * @param {NextFunction} next - The next function.
 * @returns {Promise<void>} - A promise that resolves when the function is done.
 */
export const paypalWebhookCancelledHandler = async (
  req: Request,
  res: Response,
  next: NextFunction,
) => {
  try {
    const event_type = req.body.event_type;
    const summary = req.body.summary;
    const order_id = req.body.resource.id;
    const status = req.body.resource.status;

    const webhookData = {
      event_type,
      summary,
      recurring_payment_id: subscription_id,
      status,
    };
    //perform the activity for  update the payment infoormation

    res.status(200).send({
      message: 'Webhook received successfully',
    });
  } catch (error) {
    console.error(error);
    next(error);
  }
};
Associated Context
Type Code Snippet ( .js )
Associated Tags paypalClient ID PAYPAL Client Secret PayPal Mode SANDBOX URL LIVE URL OAuth2 token endpoint paymentWithCard function extendAuthRequest method response object nextFunction reactjs facebook-opengraph facebook-php-sdk linkedin facebook-javascript-sdk payment PayPal Client ID PayPal Client Secret Sandbox URL Live URL Authentication Token Payment with Card Request URL Create Order Capture Order
💡 Smart Description This code snippet defines a function called getAuthenticationToken that returns an access token obtained from the OAuth2 token endpoint. It also includes two methods: ExtendAuthRequest, Response, and NextFunction. The PaymentWithCard function handles
The code snippet defines two functions. The first function, getAuthenticationToken, retrieves an access token for authentication using client credentials. The second function, paymentWithCard, handles the payment process using a credit card, including creating an order, capturing
🔎 Suggested Searches How to handle payment process using credit card in JavaScript?
Related Links https://api-m.sandbox.paypal.com
https://api-m.paypal.com
https://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
https://github.com/johnste/finicky/wiki/Troubleshooting-&-Tips#i-want-to-use-the-openerbundleid-option-but-i-dont-know-what-bundle-id-to-listen-to
https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/
https://developer.paypal.com/docs/api/orders/v2/
Related People Sumanta Kabiraj
Sensitive Information No Sensitive Information Detected
Shareable Link https://sumanta.pieces.cloud/?p=3da547873b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment