For example if I want to upgrade my user's package via Stripe API, from "59$ per month" package to "109$ per month" package and immediately charge (109-59=50$) / invoice the user. This is how I am doing:
prorationDate = (System.currentTimeMillis() + (30 * 1000)) / 1000L;
subscription = Subscription.retrieve(subscriptionId);
Map<String, Object> item1 = new HashMap<>();
item1.put("id", subscription.getItems().getData().get(0).getId());
item1.put("plan", newPlanId);
Map<String, Object> items1 = new HashMap<>();
items1.put("0", item1);
Map<String, Object> params1 = new HashMap<>();
params1.put("items", items1);
params1.put("proration_date", prorationDate);
// params1.put("prorate", true); deprecated and changed to the next line
params1.put("proration_behavior", "create_prorations");
params1.put("billing_cycle_anchor", "unchanged");
params1.put("payment_behavior", "pending_if_incomplete");
subscription = subscription.update(params1);
This is upgrading my user's package successfully but the invoice looks like this:
why it's also automatically subscribing for the next period ? even if I used set proration_behavior to always_invoice (when the subscription is updated to a new plan, a new invoice is paid automatically without the user paying).
Related
I am playing with Stripe-Java and I'm trying to add a card to a customer.
My code looks like this:
Customer stripeCustomer = Customer.retrieve("cus_xxxxxxx");
Map<String, Object> cardParam = new HashMap<String, Object>();
cardParam.put("number", "4242424242424242");
cardParam.put("exp_month", "11");
cardParam.put("exp_year", "2022");
cardParam.put("cvc", "123");
//token
Map<String, Object> tokenParam = new HashMap<String, Object>();
tokenParam.put("card", cardParam);
Token token = Token.create(tokenParam);
//user token
Map<String, Object> sourceParam = new HashMap<String, Object>();
sourceParam.put("source", token.getId());
//add to customer
stripeCustomer.getSources().create(sourceParam);
This works successfully on Stripe-Java version 19.45.0 but not on 20.0.0 or any versions above. Has the method to add a card changed?
A nullpointer exception is thrown
Thanks
This : stripeCustomer.getSources() will be null in v20.0.0 and above of the library because it pins to API version 2020-08-27 where customer.sources was removed by default. [0] [1]
The sources property on Customers is no longer included by default.
You can expand the list but for performance reasons we recommended
against doing so unless needed.
You would need to explicitly expand [2] "sources" when retrieving the Customer in order to populate customer.getSources()
CustomerRetrieveParams params = CustomerRetrieveParams.builder()
.addExpand("sources").build();
Customer stripeCustomer = Customer.retrieve("cus_xxxxxxx", params, null);
Also, your code uses the legacy Token API, and is passing raw card details from your server that puts you in PCI scope, you should look into the recommended integration paths : https://stripe.com/docs/payments/accept-a-payment
[0] https://github.com/stripe/stripe-java/blob/master/CHANGELOG.md#2000---2020-08-31
[1] https://stripe.com/docs/upgrades#2020-08-27
[2] https://stripe.com/docs/expand
I am trying to send some xrp with same accouts but different source and destination tag.
#SuppressWarnings("unchecked")
#Override
public Map<String, Object> makeTransaction() {
Map<String, Object> mainMap = new HashMap<>();
mainMap.put("secret", "my_secret_key");
mainMap.put("Fee", "1000"); // in drops
Map<String, Object> subMap = new HashMap<>();
subMap.put("Account", "my_ripple_account"); // source account(my_ripple_account) == destination account(my_ripple_account)
subMap.put("Amount", "1000000"); // in drops
subMap.put("Destination", "my_ripple_account"); // // source account(my_ripple_account) == destination account(my_ripple_account)
subMap.put("TransactionType", "Payment"); // since we are making a payment request
subMap.put("SourceTag", 400123);
subMap.put("DestinationTag", 400555);
mainMap.put("tx_json", subMap);
JSONObject j = new JSONObject(mainMap);
JSONObject json = new JSONObject();
json.put("method", "submit");
json.put("params", new JSONArray("[" + j.toString() + "]"));
String requestData = json.toString();
Map<String, Object> responseMap = restTemplate.postForObject("http://my_ip:5005",
requestData, HashMap.class);
LOGGER.debug("makeTransaction() : Response is {}.", responseMap);
return responseMap;
}
Example Explanation:
Here source account(my_ripple_account) = destination account (my_ripple_account) and sourceTag = 400123 and destinationTag=400555.
So transaction withing same account here.
Example Output:
{
"result": {
"deprecated": "Signing support in the 'submit' command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
"engine_result": "temREDUNDANT",
"engine_result_code": -276,
"engine_result_message": "Sends same currency to self.",
"status": "success",
"tx_blob": "12000022800000002300061AFB24000000022E000F13066140000000000F424068400000000000000A732102898F54F50F2FCEC11B164D7AA7528B4D7261077913F20579EE99F064C1D1500874473045022100AB07788C4C19D642C60BC552986022E31885E93CD92D6DBEA2B6A1FC9B3AA3B002207837AEA67150CE5CC84FB22C4E90F5D1954BB5446460D2852E7F08E1A1EDF52F811436DB2A0AD63A50E5188C806E2EA5595F2D777D91831436DB2A0AD63A50E5188C806E2EA5595F2D777D91",
"tx_json": {
"Account": "rarhswhyFr8TGFPCsY9tTiK5KHUZn4hQaA",
"Amount": "1000000",
"Destination": "rarhswhyFr8TGFPCsY9tTiK5KHUZn4hQaA",
"DestinationTag": 987910,
"Fee": "10",
"Flags": 2147483648,
"Sequence": 2,
"SigningPubKey": "02898F54F50F2FCEC11B164D7AA7528B4D7261077913F20579EE99F064C1D15008",
"SourceTag": 400123,
"TransactionType": "Payment",
"TxnSignature": "3045022100AB07788C4C19D642C60BC552986022E31885E93CD92D6DBEA2B6A1FC9B3AA3B002207837AEA67150CE5CC84FB22C4E90F5D1954BB5446460D2852E7F08E1A1EDF52F",
"hash": "559DB6081DF88E699EDC5ECFFDA7CFC669D40975AFA4E5C376123D7EB7AC2A10"
}
}
}
Output Explaination:
Output indicates status=success but engine_result=temREDUNDANT and there is no change in tag balance even if status=success..
Imagine if you had a wallet(real physical wallet) with some bills in it. You're doing the same thing as if you've:
pull out your wallet
bring a few bills out
swap their places
put them back in your wallet
In the end you've still got the same amount of money you had in the first place.
Is the order of the bills important to you?
If yes then you keep track of it to yourself. (you wouldn't pay a fee as a plus!)
That's just how ripple's account & destination tag model works.
destinationTag does not have a balance, It's just a measure of differentiation of your transactions.
I am working with Stripe Customers, Subscription and Cards.
Now, I have a scenario where, Customer can have multiple cards.
Now, Customer adds a new card. And I have to mark that new added card as default_source.
So what I am doing is
Map<String, Object> params = new HashMap<String, Object>();
params.put("source", token.getId());
Customer customer = Customer.retrieve(user.getStripeId());
customerId = customer.getId();
Customer updatedCustomer = customer.update(params);
This piece of code is updating a customer and marking the current card as default_source which is as expected.
But if the Customer already has card then it overrides the old Card with new one. So the old card is deleted from that Customer.
Now what I want is, If Customer already have the card then I want to mark that card as secondary and then add new card and mark it default_source.
So how can i do that?
You'll want https://stripe.com/docs/api/sources/attach?lang=java and https://stripe.com/docs/api/customers/update?lang=java#update_customer-default_source :
Customer customer = Customer.retrieve(user.getStripeId());
// add a new payment source to the customer
Map<String, Object> params = new HashMap<String, Object>();
params.put("source", token.getId());
Source source = customer.getSources().create(params);
// make it the default
Map<String, Object> updateParams = new HashMap<String, Object>();
updateParams.put("default_source", source.getId());
customer.update(updateParams);
The user logs in on the website and creates different events. This event is saved into the neo4j database as a node and I make the "EVENT_CREATOR" realtionship between the user and the event node.
I am trying to implement pagination for all the user's events on my website (using Play2 framework) and I need for example if user accesses the first page, I load the first ten events; 2nd page to load the 10th- 20th events, and so on...
this is my query:
match(n);
...
skip k;
limit 10;
return n;
At the moment I am getting all the events created by the user and add them to the array list.
private static List<PublicEvent> getEvents(int page, int pageSize) {
List<PublicEvent> events = new ArrayList<PublicEvent>();
GraphDatabaseService db = Neo4JHelper.getDatabase();
try (Transaction tx = db.beginTx()) {
Index<Node> userIndex = db.index().forNodes(ModelIndex.Users);
IndexHits<Node> userNodes = userIndex.get(ModelGraphProperty.UserProfile.UserName, SessionUtilities.getCurrentUser());
Node me = userNodes.next(); //current logged in user
PagingIterator paginator = new PagingIterator(me.getRelationships(GraphRelation.RelTypes.EVENT_CREATOR).iterator(), pageSize); // get all the events that were created by this user
paginator.page(page);
// adding all the created events by this user to an array
if (paginator.hasNext()) {
Relationship eventCreator = (Relationship)paginator.next();
Node event = eventCreator.getOtherNode(me);
events.add(new PublicEvent(event));
}
tx.success();
}
db.shutdown();
return events;
}
I want to update the code to run Cypher queries and I add the following lines of code (using the example https://www.tutorialspoint.com/neo4j/neo4j_cypher_api_example.htm )
GraphDatabaseService db = Neo4JHelper.getDatabase();
ExecutionEngine execEngine = new ExecutionEngine(db); //HERE I GET AN ERROR
ExecutionResult execResult = execEngine.execute("MATCH (n) RETURN n");
String results = execResult.dumpToString();
System.out.println(results);
it is expecting a second parameter: logger. What is the error or is there anything I am doing wrong?
RestGraphDatabase db= (RestGraphDatabase)Neo4JHelper.getDatabase();
RestCypherQueryEngine engine=new RestCypherQueryEngine(db.getRestAPI());
Map<String, Object> params = new HashMap<String, Object>();
params.put( "id", eventId );
String query="match (s) where id(s) = {id} return s;";
QueryResult result=engine.query(query,params);
if(result.iterator().hasNext()) {
//HERE PUT WHATEVER YOU NEED
}
Take a look at the documentation:
https://neo4j.com/docs/java-reference/current/
Cannot figure out for the life of me how to do this. I've tested the following which isn't working;
String stripeCustomerID = "123";
Customer cu = Customer.retrieve(stripeCustomerID);
cu.setDefaultSource(token);
Map<String, Object> updateParams = new HashMap<String, Object>();
updateParams.put("default_source", token);
enter code here`cu.update(updateParams);
This is the only place the Stripe API documentation hasn't had the answer.
Has anyone implemented this previously?
Regards,
Michael
default_source is expecting a card id not a token id. Thus you either need to:
1) Add the card to the customer and then update the default_source property
or
2) You can set the source property of the customer to the token. By setting source you will add the new card, delete the old default_source, and then set the new one as the default, all in the same API call.
Answer thanks to Matthew;
Customer cu = Customer.retrieve(stripeCustomerID);
Map<String, Object> updateParams = new HashMap<String, Object>();
updateParams.put("source", token);
cu.update(updateParams);