hello I create solana wallet with the following code on my nodejs server.
const SolanaWeb3 = require("#solana/web3.js");
SolanaWeb3.Keypair.generate();
I don't think this is an active wallet. Because I haven't paid the rent fee for this account.
**So I want to know when is the moment when this inactive account pays the rent fee.
(I want to know if it is activated when a transaction in which sol is deposited into this account occurs, or whether this account should generate a transaction that sends solana to another place.)
And I want to know if there is a javascript function that gives rent fee when account is created.**
thank you for your reply.
To your second question
And I want to know if there is a javascript function that gives rent fee when account is created
Yes there is. Assuming you just want a system account that holds SOL versus an account that has data:
// amount of space to reserve for the account. system accounts are 0 space
const space = 0;
// Get the rent, in lamports, for exemption
const rentExemptionAmount =
await connection.getMinimumBalanceForRentExemption(space);
To your first question
If you already have a funded account (fromKeyPair), you can use that accounts public key to fund the new account you want to create:
const newAccountKeypair = SolanaWeb3.Keypair.generate();
const createAccountParams = {
fromPubkey: fromKeyPair.publicKey,
newAccountPubkey: newAccountKeypair.publicKey,
lamports: rentExemptionAmount,
space,
programId: SolanaWeb3.SystemProgram.programId,
};
const createAccountTransaction = new SolanaWeb3.Transaction().add(
SolanaWeb3.SystemProgram.createAccount(createAccountParams)
);
await SolanaWeb3.sendAndConfirmTransaction(connection, createAccountTransaction, [
fromKeyPair,
newAccountKeypair,
]);
Related
I'm using Stripe and am trying to implement the scenario described here
The frontend is making a call to the backend that has this code
var service = new PaymentIntentService();
var createOptions = new PaymentIntentCreateOptions
{
PaymentMethodTypes = new List<string>
{
"card",
},
Amount = (long?)(payment.Amount * 100),
Currency = "EUR"
};
var result = await service.CreateAsync(createOptions);
return result.ClientSecret
In the documentation it says that the below code should be run "later" but it doesn't specify when. In my case I would prefer submitting the transfers to Stripe as soon as possible and preferably connecting them to the above payment so the transfers would be automatically handled by Stripe when the payment is done.
As I read the documentation (https://stripe.com/docs/api/transfers/create#create_transfer-source_transaction) SourceTransaction could be used for this.
var transferService = new TransferService();
var transfer1Options = new TransferCreateOptions
{
Amount = 100,
Currency = "eur",
Destination = "{{CONNECTED_STRIPE_ACCOUNT_ID}}",
SourceTransaction = result.Id
};
var transfer1 = transferService.Create(transfer1Options);
The result -variable contains a Charges -list but that is empty and when doing the above, i.e. adding the payment intent's id to SourceTransaction property, I get an error that the charge does not exist.
In the documentation it says that the below code should be run "later" but it doesn't specify when
It's whenever you are ready to make the transfer, after the payment has succeeded, essentially.
As I read the documentation (https://stripe.com/docs/api/transfers/create#create_transfer-source_transaction) SourceTransaction could be used for this.
Yep, you should definitely use source_transaction here! Otherwise the transfers won't succeed since the funds would not be available yet.
The result -variable contains a Charges -list but that is empty and when doing the above, i.e. adding the payment intent's id to SourceTransaction property, I get an error that the charge does not exist.
The value to pass to source_transaction is indeed the intent.charges.data[0].id , of a PaymentIntent that has succeeded and has a Charge.
You don't have a Charge ID because you haven't actually processed a payment yet. Creating a PaymentIntent doesn't process a payment.
You have to do the normal full PaymentIntent integration by building a form that collects payment details and 'confirms' the PaymentIntent, that's the action that processes the payment, and after that succeeds, the charges array will have a Charge in it that can be used for the transfer. For example you might create the transfer as part of handling the payment_intent.payment_succeeded webhook event.
https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements
I have a flow using nodejs and reactjs to let users subscribe to my site.
So when user logs in he can see a few packages.
When the user selects a package and enters card details, I do the following:
1 - Create a new customer, based on user details (name, email etc, fetched since user logged in)
2 - Create a subscription for the newly create customer according to price_id selected
3 - Collect in the frontend the card number/cvc/expire date with:
const cardElement = elements.getElement(CardElement);
4 - Make a call to stripe from frontend with:
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: name,
}
}
});
Im not sure if this was the best flow. However, it is working.
I also managed updating subscription and canceling it.
However, Im having an hard time in changing credit card details.
What I understood from docs I should use the same call as I did when I create the card payment.
So I collect again the credit card number and call again the same function:
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: cardElement,
billing_details: {
name: name,
}
}
});
However, the call is done to:
https://api.stripe.com/v1/payment_intents/pi_XXXX/confirm
and returns a 400 with this info:
type: "invalid_request_error", code: "payment_intent_unexpected_state", doc_url: "https://stripe.com/docs/error-codes/payment-intent-unexpected-state"
Should I use something else to update credit card info? Or am I calling it in the wrong way?
Your initial flow of calling confirmCardPayment() is correct, that is what is recommended in Stripe's docs too: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements.
hard time in changing credit card details. What I understood from docs I should use the same call as I did when I create the card payment.
To just collect card details and create a PaymentMethod, you should call createPaymentMethod() [0] from Stripe.js. That will convert a customer's card into a PaymentMethod like pm_123.
You will then send that PaymentMethod to your backend server, where (using your server-side Stripe API library like stripe-node) you'll attach it to a Stripe Customer [1] and also update as the Customer's default PaymentMethod for recurring payments [2].
[0] https://stripe.com/docs/js/payment_methods/create_payment_method
[1] https://stripe.com/docs/api/payment_methods/attach
[2] https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method
I am using React and Stripe payments for subscriptions. I have the checkout all set using Elements. I want to add the possibility for a user to add a promo code set up in stripe that will be added to the subscription on creation.
What i want to do is check that the promo code is valid (after checking the various subscriptions on the code) and show the affect to the customer before they commit to subscribe. I thought there would have been something built into the API but apparently not. And Stripe support desk (which is generally very good) don't don't seem to know why i want to check a code is valid and show customer it is before they actually click subscribe.
const promotionCodes = await stripe.promotionCodes.list({
active: true,
code: promoCode,
});
if (promotionCodes.data.length > 0) {
const today = Math.floor(Date.now() / 1000);
const expiry =
promotionCodes.data[0].expires_at ||
Math.floor(Date.now() / 1000) + 20;
if (today <= expiry) {
valid = true;
}
}
This is retrieving the code (there can only be 1 active result so it gets it fine). I then check its not expired. All fine, the data I cannot get is if the Coupon the Promotion code is attached to, is restricted to only certain products. For example, if i chose gold plan and try to use a code for silver plan then it would be invalid.
So i have a customer which already has a card created.
On the frontend, i give the option to use the existing card or a different one.
Following the API docs, for the new card, i create the token, send it to my backend...
In the backend:
const paymentInfo = {
customer: customerId,
amount: Number(total) * 100,
currency: 'usd',
source: existingCardId || token
}
const charge = await stripe.charges.create(paymentInfo)
If i pay with the existing card, the charge goes through, but if i send a new token, I get an error back:
Customer cus_G4V0KvxKMmln01 does not have a linked source with ID tok_1FYMLTAOg97eusNI2drudzlJ.
From the API Docs:
https://stripe.com/docs/api/charges/create
source optional A payment source to be charged. This can be the ID of
a card (i.e., credit or debit card), a bank account, a source, a
token, or a connected account. For certain sources—namely, cards, bank
accounts, and attached sources—you must also pass the ID of the
associated customer.
I found the solution:
if (token) {
const card = await stripe.customers.createSource(customerId, {
source: token
})
paymentInfo.source = card.id
}
I store the id from each Charge and associate with a purchase.
I have connected accounts in my application. I want to show them the breakdown of purchases per payout. To do that I need a way to get the list of charge_ids per payout.
I received an official response from stripe, there is no way to do it in one query but there is a way.
1) a charge ch_xxxx and a related transaction (txn_xxxxxx) is created
on platform account
After the platform receives the charge, platform account will create a
transfer to the connected account (tr_xxxxxx) and the transfer object
is on Platform Account as well
2) When connected account received the transfer, an payment object
will be created (py_xxxxxx) and a related transaction (txn_xxxxx) On
the connected account, these payment transactions will be grouped
together and paid out in a "po_xxxxxx"
So between platform account and connected account, from connected
account payout to charge, the overall flow looks like this:
payout (po_xxxx) -> transactions (txn_xxxx) -> payment(py_xxxx) ->
transfer(tr_xxxx) -> charge (ch_xxxxx)
public static void ListTransactionsForPayout(String payout) throws StripeException {
//1. Get a list of transactions for payout in Connected account
Map<String, Object> balancetransactionParams = new HashMap<String, Object>();
balancetransactionParams.put("limit", 20);
balancetransactionParams.put("payout", "po_1Dy8ZfKxxxxxx");
List<String> expandList = new LinkedList<String>();
expandList.add("data.source");
balancetransactionParams.put("expand", expandList);
RequestOptions requestOptions = RequestOptions.builder()
.setStripeAccount("acct_connected_account")
.build();
BalanceTransactionCollection transactions = BalanceTransaction.list(balancetransactionParams, requestOptions);
for (BalanceTransaction txn : transactions.autoPagingIterable()) {
if (txn.getType().equals("payment")) {
Charge charge = (Charge) txn.getSourceObject();
// 2. Get transfers from payment and get charge from transfer
Transfer transfer = Transfer.retrieve(charge.getSourceTransfer());
System.out.printf("txn %s -> payment %s -> transfer %s -> charge %s\n", txn.getId(), txn.getSource(), transfer.getId(), transfer.getSourceTransaction());
}
}
}