Application fees error in Stripe Terminal (Direct charge) - stripe-payments

I want to collect application fees in direct charge concept with Stripe Terminal but Am getting error" Can only apply an application_fee_amount when the PaymentIntent is attempting a direct payment (using an OAuth key or Stripe-Account header)". when i use destination charge its work fine but i want to use direct charge. below code is for destination code.Please help me how i can get application fee in direct charge.
public void paymentIntent() {
PaymentIntentParameters params = new PaymentIntentParameters.Builder()
.setAmount(usdamount)
.setCurrency("usd")
.setApplicationFeeAmount(usdapplicationfee)
.setDescription("Order#" + orderref)
.setMetadata(initialMetadata)
.setOnBehalfOf(accountid)
.setTransferDataDestination(accountid)
.build();
Terminal.getInstance().createPaymentIntent(params, new PaymentIntentCallback() {
#Override
public void onSuccess(PaymentIntent paymentIntent) {
collecetpayment(paymentIntent);
}
#Override
public void onFailure(TerminalException exception) {
accounterror(exception.getErrorMessage(), exception.getMessage());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
finish();
}
});
}

So it's a little complex, because for direct charges to succeed the PaymentIntent,
Reader, Location, and Connection must exist on the connected account. That means that you must pass the Stripe-Account header when creating these objects.
If you use direct charges, all Terminal API objects belong to connected accounts.
Here's the flow to create a direct charge with application fee with Terminal:
Your server creates the PaymentIntent on the connected account (by passing the Stripe-Account header) & sets the application fee.
(p400 only) Your server creates a Location on the connected account
(p400 only) Your server registers a Reader to that Location (passing the Stripe-Account header)
Your server creates a Connection token on the connected account
Note that steps 2 & 3 only apply to the Verifone reader—the bluetooth-based reader will register itself and your app's current location when integrated with the Stripe Terminal SDK.
After initializing Terminal with the Connection from step 4, you can pass the PaymentIntent from Step1 to Terminal.instance().collectPaymentMethod(), .processPayment(). Because the Connection and PaymentIntent are both attached to the connected account, the Terminal SDK will be able to process the direct charges.
There doesn't seem to be an example of this in the Stripe docs at the moment, so if you get stuck I'd recommend asking on their IRC channel (#stripe on freenode) or emailing Stripe support.

Related

How to send transaction from metamask wallet to backend node js

i am building simple dapp application where i want to verify something and then only make contract interaction but right now i am struggling to put a middleware which will act like user will make txn through metamask and then this txn or something will go to backend server on any language probably node js , and i will do some checking and if all good then Send it to block chain.
Any suggestion?
Right now its all in react Frontend and metamask browser extension.. and i can not make client side code restricted
And i can not ask for private key even.
Not possible by design. A transaction needs to be signed by the sender's private key. So unless the users are willing to give you their private key (so that you could sign the transaction for them on the backend), you'll need to change your approach.
If you need to allow interaction with the contract only to users authorized by your app, the contract needs to hold the list of authorized addresses. And the list can be updated by your app (that holds the private key to the owner address). Example:
pragma solidity ^0.8;
contract MyContract {
address public owner = address(0x123);
mapping(address => bool) public isAuthorized;
function setAuthorized(address _address, bool _isAuthorized) external {
require(msg.sender == owner, 'Only the contract owner can set authorized addresses');
isAuthorized[_address] = _isAuthorized;
}
function foo() external {
require(isAuthorized[msg.sender], 'Only authorized addresses can execute this function');
// ...
}
}

How to prevent creating duplicate subscription in stripe when trial period is set on subscription

I am encoutering a problem with stripe. let me explain my working
scenario.my requirement is do not charge user for 14 days with card up front
1)user enter card details
2)sca popup appear
3)regardless of user complete the authentication or not a subscription is created in stripe because i set trial_end_date=>now()+14 days
4)user payment fails in some reason and attempt again, another subscription created
i am worried about the duplicate subscription as the stripe will attempt to pay after the 14 days for both of these subscription as it send a Stripe-hosted link for cardholders for both of these subscription
let me give a snapshot of what i have so far
$data['customer']='customerId';
$data['items']=[];
$data['items'][0]['plan']='stripe_plan_id'
$data['default_payment_method']='pm_xxxx'
$data['trial_end']= strtotime('+14 days');
$data['prorate']=true;
$data['tax_percent']=env('VAT_PERCENTAGE');
$data['expand']= ['latest_invoice.payment_intent', 'pending_setup_intent'];
try {
$subscription=\Stripe\Subscription::create($data);
}
catch(Exception $e) {
return response()->json(['success' => false,'message'=>$e->getMessage()]);
}
what i am missing? how to prevent the duplicate subscription scenario.please expain with the correct example which is i am missing.thanks in advance
I think the problem is in your payment flow, there is not a stripe api that explicitly detects duplicate subscription. You are after all allowed to assign more then 1 subscription per customer id. You can create idempotent keys, but that isn't for the same thing you're talking about, idempotent keys are for accidently hitting the submit button twice within the same timeframe.
The solution would be to attach a payment method to your stripe customer id before your subscription trial is over. For example if you are using stripe elements you would call
Node/JS Example below :
const result = await stripe.createPaymentMethod({
type: 'card',
card: card
})
then pass that result to your backend
const result = await stripe.paymentMethods.attach(paymentMethodId, {customerId})
You do not need to create a new subscription, as one has already been created for that user. Credit cards are assigned to customer Ids, and not to subscriptions. Stripe will do the rest.
You do also need to update the customer with the default payment method as follows :
const customer_update = await stripe.customers.update(stripeCustomerId,{invoice_settings: {default_payment_method:paymentMethodId}});
Now when you visit your dashboard you will see a default card assigned to your customer. Once the subscriptions falls out of the trail period, the default card will be charged.
So in this case there wont be a duplicate subscription created, as you are not calling stripe.subscriptions.create again.

How to implement Paypal subscription in a vue application?

I am working on a project which needs to deducts a fixed amount from a user's account to a business account on monthly basis. I am trying to create a Paypal button client side (vue) for accepting subscriptions on monthly basis. The users deduction information on monthly basis shall be stored in a database. The user shall also provided an option to cancel the subscription. Any help would be greatly appreciated.
Well i found out an answer after a little digging in the documentation provided at https://developer.paypal.com/docs/subscriptions/integrate and went through the steps they provided.
Steps
Create a product through their API by providing access_token in the headers.
After the product has been created, get product-Id from response and then create plan using the product_id in request body.
After the plan has been successfully created copy Plan_id and replace the id in smart subscription button.
paypal.Buttons({
createSubscription: function(data, actions) {
return actions.subscription.create({
'plan_id': 'P-your_plan_id'
});
onApprove: function(data, actions) {
alert('You have successfully created subscription ' + data.subscriptionID);
}
}

Stripe connect share card source not working

I am saving customers and their sources on my platform, and trying to create charges for my connected accounts. I am able to successfully create destination charges, but I'm having trouble with creating direct charges.
I've tried creating a token per: https://stripe.com/docs/connect/shared-customers
If I create a token using just the customer the example, the error is:
'You provided a customer without specifying a source. The default source of the customer is a source and cannot be shared from existing customers.'
Even though the documentation says that you need "The card or bank account ID for that customer, if you want to charge a specific card or bank account rather than the default".
I cannot find a parameter that lets me specify a source as well or instead of a customer.
I've tried sharing the customer's chosen source with the connected account per: https://stripe.com/docs/sources/connect#shared-card-sources
which results in the error:
'Sending credit card numbers directly to the Stripe API is generally unsafe. We suggest you use test tokens that map to the test card you are using, see https://stripe.com/docs/testing.'
I tried attaching a test token (tok_visa) to my customer, and creating a charge with that, but that had the same result.
Every time I have some success I end up with the error about sending numbers being unsafe even though I'm only ever sending Stripe's provided token or source ID's.
I've tried this:
const newToken = await stripe.tokens.create({
customer: customerId,
}, {
stripe_account: stripeAccountId,
}).catch((e) => {
console.log(e);
});
and this:
const newToken = await stripe.sources.create({
customer: customerId,
usage: 'single_use',
original_source: sourceId,
}, {
stripe_account: stripeAccountId,
}).catch((e) => {
console.log(e);
});
The only success I've had is creating the direct charge with a test token (tok_visa), completely bypassing the sharing of tokens/sources. No other combination seems to work. But that leaves me at a loss as to how to get a real shared token when I need it.
I found out I should be using sources, not tokens. And it turns out I was accidentally using the whole newToken as the source for the charge. It's working now that I'm passing the newToken.id to the charge.

Duplicate registrations in Azure Notification Hub with Xamarin Android

I am using Azure Notification Hub with Xamarin Android. It works fine in normal scenario and I am able to get push notifications on my registered tags but on update of tag or reregistering the hub it creates duplicate registrations. Also the tags which were removed post registration still gets the notification. Below is the sample snippet for the same
try
{
Hub.UnregisterAll(registrationId);
}
catch (Exception ex)
{
}
var tags = getting active tags
try
{
var hubregistration = Hub.Register(registrationId, tags);
}
catch (Exception ex)
{
}
AFAIK, the Registration Token (registrationId) issued by GCM is used to identity the client app, and it may be the same when re-register from GCM without unregistering from GCM. Based on your code, you are using the Registrations model. Hub.UnregisterAll(registrationId) would try to un-register the registrations with the same Registration Token (pnsHandle) from your azure notification hub.
I would recommend you capturing the exception when you call UnregisterAll. Also, you could leverage Server Explorer from Visual Studio, choose your notification hub, then view and manage all the registrations in your hub as follows to narrow this issue:
Note: You could check with your device registrations and try to find whether you could retrieve the duplicated registrations (same PNS Identifier (Registration Token), different tags / Azure Registration ID or different PNS Identifier (Registration Token) for the same client app, etc.).
If you find different PNS Identifier (Registration Token) for the same client app, I assume that your client app need to store the previous Registration Token and compare with the latest Registration Token, UnregisterAll the old Registration Token if not match firstly, then register the new Registration Token with your notification hub.
Additionally, the Installations model could avoid the duplicate registrations. For more details, you could refer to Registration management.
This is my working methods for Register and UnRegister from azure hub
void unregister ()
{
try {
NotificationHub hub = new NotificationHub (Constants.NotificationHubName, Constants.ListenConnectionString, this);
hub.UnregisterAll (FirebaseInstanceId.Instance.Token);
} catch (Exception ex) {
}
}
void register ()
{
try {
NotificationHub hub = new NotificationHub (Constants.NotificationHubName, Constants.ListenConnectionString, this);
var tags = new List<string> () { ... };
hub.Register (FirebaseInstanceId.Instance.Token, tags.ToArray ());
} catch (Exception ex) {
}
}
based on this documentation https://learn.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm

Resources