Paypal Order API capture payment in Angular and NestJS - paypal

My stack is NestJS and Angular12, I am using the OrderAPI v2.
I succesfully implemented the order flow using an SDK button, but, since I have several payment systems that are activated by a single button "Pay now", I need to avoid SDK in my front end. Follows the methods I use to create and capture payments, and they works with the SDK button.
async createOrder(value: number): Promise<any> {
const accessToken = await this.generateAccessToken();
const url = this.baseUrl+`/v2/checkout/orders`;
const body = {
intent: "CAPTURE",
return_url: process.env.CLIENT+"/success",
purchase_units: [
{
amount: {
currency_code: "EUR",
value: value.toFixed(2)
}
}
]
}
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`
}
const obs = this.httpService.post(url, JSON.stringify(body),{headers: headers});
const response = await firstValueFrom(obs);
return response.data;
}
async capturePayment(order: CreateOrderDto, orderId: string): Promise<any> {
const accessToken = await this.generateAccessToken();
const url = this.baseUrl+`/v2/checkout/orders/${orderId}/capture`;
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`
}
const obs = this.httpService.post(
url,
{},
{
headers: headers
}
)
const response = await firstValueFrom(obs);
if (response.data.success) await this.orderService.createOrder(order)
return response.data;
}
When calling the createOrder() function I return the url of the approvation, and in my Front-end I do the redirect to the approve page of Paypal. The problem is that when approving the transaction on the approve url the user is shown a infinite loading page.
Is there something I am missing?

Related

i could not accept the payment using flutter 'checkout.com'

I'm trying to enable payment in my app so i choose 'checkout.com' as a payment gateway
there are couples of methods there to accept the payment and i choose the one with token.
i managed to get the token successfully, but accepting the payment does not work. i am not sure if my code is wrong, or their API is broken for some reason. because it does not response me any data or anything the error code is 401
here is my code
Future<bool> makePayment(PaymentCard card, int amount) async {
String? token = await _getPaymentToken(card);
Map<String, dynamic> body = {
"source": {"type": "token", "token": token},
"amount": amount,
"currency": "USD",
};
http.Response respone = await http.post(Uri.parse(_paymentURL),
headers: _Payment_Header, body: jsonEncode(body));
print(respone.body);
if (respone.statusCode == 200) {
var data = await jsonDecode(respone.body);
print(data['response_summary']);
return true;
} else {
print("invalid - payment");
return false;
}
}
static const Map<String, String> _Payment_Header = {
'Content-Type': 'Application/json',
'Authorization': _secret_key,
};
the response body is empty.
this is the url
static const String _paymentURL = 'https://api.sandbox.checkout.com/payments';
also the secret key is correct.
any idea why ? thank you
Could be a couple of issues. You are most likely on the new platform which requires the word Bearer in front of the secret key. Your authorization header value would look similar to 'Bearer sk_xxxx'

How to do a Razorpay integration in Flutter

I am able to deploy payment transaction but the server part is very hard. How can I create a orderid and how can we find the payment is done by a specific user?
Hope you set up all the necessary things.
Step 1: creating Order using Razorpay official Order Api:
void createOrder() async {
String username = 'xxxxxxxxxx';// razorpay pay key
String password = "xxxxxxxxxxxxxxxx";// razoepay secret key
String basicAuth =
'Basic ${base64Encode(utf8.encode('$username:$password'))}';
Map<String, dynamic> body = {
"amount": 1 * 100,
"currency": "INR",
"receipt": "rcptid_11"
};
var res = await http.post(
Uri.https(
"api.razorpay.com", "v1/orders"), //https://api.razorpay.com/v1/orders // Api provided by Razorpay Official 💙
headers: <String, String>{
"Content-Type": "application/json",
'authorization': basicAuth,
},
body: jsonEncode(body),
);
if (res.statusCode == 200) {
openCheckout(jsonDecode(res.body)['id']); // đŸ˜ŽđŸ”„
}
print(res.body);
}
//*#################################################################
Step 2: Open Razorpay checkout interface.
After getting orderId from Razorpay official Api, pass the id when calling openCheckout(jsonDecode(res.body)['id']); function
void openCheckout(String orderId) async {
var options = {
'key': 'xxxxxxxxxxxxxxxx',
"amount": 1 * 100,
'order_id': orderId,
'name': 'main.co.in',
// 'prefill': {'contact': '', 'email': 'test#razorpay.com'},
'external': {
'wallets': ['paytm']
}
};
try {
razorpay.open(options);
} catch (e) {
debugPrint('Error: e');
}
}
3rd Step: Signature verification.
This is important if you automatically wanna transfer your amount to your bank account.
for Hmac SHA key , install this package: crypto:
handlerPaymentSuccess(PaymentSuccessResponse response) {
final key = utf8.encode('NgDLPyiDRPuQpcXy1E3GKTDv');
final bytes = utf8.encode('${response.orderId}|${response.paymentId}');
final hmacSha256 = Hmac(sha256, key);
final generatedSignature = hmacSha256.convert(bytes);
if (generatedSignature.toString() == response.signature) {
log("Payment was successful!");
//Handle what to do after a successful payment.
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("Success : payment successful"),
// content: const Text("Are you sure you wish to delete this item?"),
actions: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.of(context).pop(true);
// PlaceOrderPrepaid();
},
child: Text("OK"))
// ),
],
);
},
);
} else {
log("The payment was unauthentic!");
}
}

How to send and verify OTP using cloud function in flutter?

I have API to send and verify otp code. I need to link that API to my flutter app using Firebase clod function. How is it possible Please help ?
Setup firebase cloud function here
Your js code be like
exports.sendOtp = functions.https.onCall((request, response) => {
const options = JSON.stringify({
mobile: request.text,
});
const headers = {
"Authorization": "Bearer xxxxxxxxxxxxxxxxxxxxxxx”,
};
const res = axios.post(“url”, options, {headers: headers}).then((response) => {
console.log(response);
return response;
});
return res.statusCode;
});
Your service code be like
Future<void> sendOtp(String mobile) async {
HttpsCallable callable =
FirebaseFunctions.instance.httpsCallable('sendOtp');
final resp = await callable.call(<String, dynamic>{
'text': mobile,
});
}

Stripe Connect firebase functions for creating seller account

I'm using Firebase functions for creating seller account but I don't know how to create seller account and what to put in the redirect_url
I followed some tutorials and wrote the below code
Let me know what changes should I do to open seller account registration with url_launcher
Thanks
const stripeAccount = functions.https.onRequest(async (req, res) => {
const { method } = req
if (method === "GET") {
// CREATE CONNECTED ACCOUNT
const { mobile } = req.query
const account = await stripe.accounts.create({
type: "express",
})
const accountLinks = await stripe.accountLinks.create({
account: account.id,
refresh_url:, <-- What to put here
return_url:, <-- What to put here
type: "account_onboarding",
})
if (mobile) {
// In case of request generated from the flutter app, return a json response
res.status(200).json({ success: true, url: accountLinks.url })
} else {
// In case of request generated from the web app, redirect
res.redirect(accountLinks.url)
}
} else if (method === "DELETE") {
// Delete the Connected Account having provided ID
const {
query: { id },
} = req
console.log(id)
const deleted = await stripe.accounts.del(id)
res.status(200).json({ message: "account deleted successfully", deleted })
} else if (method === "POST") {
// Retrieve the Connected Account for the provided ID
// I know it shouldn't be a POST call. Don't judge :D I had a lot on my plate
const account = await stripe.accounts.retrieve(req.query.id)
res.status(200).json({ account })
}
const stripeReAuth = async (req, res) => {
const { account_id: accountId } = req.query
const accountLinks = await stripe.accountLinks.create({
account: accountId,
refresh_url: <-- Here
return_url: , <-- Here
type: "account_onboarding",
})
res.redirect(accountLinks.url)
}
})
This is my flutter code, I'm retrieving the return_url and launching it with url_launcher
class StripeBackendService {
static String apiBase = '{function address}/stripeAccount';
static String createAccountUrl =
'$apiBase/account?mobile=true';
static String checkoutSessionUrl =
'${StripeBackendService.apiBase}/checkout-session?mobile=true';
static Map<String, String> headers = {'Content-Type': 'application/json'};
void createSellerAccount() async {
var url = Uri.parse(StripeBackendService.createAccountUrl);
var response = await http.get(url, headers: StripeBackendService.headers);
Map<String, dynamic> body = jsonDecode(response.body.toString());
await canLaunch(body['url']) ? await launch(body['url']) : throw 'Error'
}
}
The refresh url should point to an address that retries the creation of the stripe connect account, in case your current http function returns an expired link. The return url is the address that the potential stripe connect user gets sent to after the stripe onboarding is complete. In knowing that address you can use the webview controller to jump back to the app when reaching that return-url endpoint.

How do I add body for PayPal partial refund to Axios?

I'm trying to post a partial refund to PayPal using Axios. If I use an empty object as the body I can complete a full refund. But I don't know how to add a body that will complete a partial refund. Here is my current code:
const axios = require('axios');
const qs = require('qs');
const refund = await axios.post("https://api-m.sandbox.paypal.com/v1/payments/capture/"
+ "myTransactionID" + "/refund",
qs.stringify({data:{amount:{currency_code:'USD',value:'20.00'}}}), //this works if I just use {};
{
headers: {
"Content-Type": `application/json`,
"Authorization": `Bearer ${ "myPayPalAccessToken" }`
},
});
console.log("refund: " + JSON.stringify(refund));
I get a "Request failed with status code 400" when I do this. I'm not sure if using a data object is necessary. Please help me figure out the syntax.
I figured it out. I should have been using application/json for the Content-Type. There was no need to stringify the body:
const axios = require('axios');
const qs = require('qs');
const PAYPAL_OAUTH_API = 'https://api.sandbox.paypal.com/v1/oauth2/token/';
const PAYPAL_PAYMENTS_API = 'https://api.sandbox.paypal.com/v2/payments/captures/';
const PayPalAuthorization = await axios({
method: 'POST',
url: PAYPAL_OAUTH_API,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Credentials': true
},
data: qs.stringify({
grant_type: 'client_credentials'
}),
auth: {
username: PAYPAL_CLIENT,
password: PAYPAL_SECRET
}
});
const PayPalToken = PayPalAuthorization.data.access_token;
const refund = await axios({
url: PAYPAL_PAYMENTS_API + "myTransactionID" + '/refund',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ PayPalToken }`
},
data: {
amount: {
value: "10.99",
currency_code: "USD"
},
invoice_id: "INVOICE-123",
note_to_payer: "Defective product"
}
});
If you are posting an invoice_id don't forget to change the number for subsequent refunds.
Also check out these links:
https://developer.paypal.com/docs/checkout/integration-features/refunds/
https://developer.paypal.com/docs/api/payments/v2#captures_refund