Paypal "create" adaptive payments being instantly charged - java

I'm trying to set up a payment system with paypal for a site where the charging should not happen at payment confirmation time. I understand this is what the "CREATE" action type is for, you make the payment and then you use the execute payment to actually charge the account. Unfortunately, from what I'm seeing in the sandbox, the buyer gets charged immediately, and the execute payment returns a "paykey already used for a payment" error. The IPN notification similarly tells me the payment has already happened.
I'm currently using adaptive payments with 2 receivers. I'm sending the request from Java, using the code pasted below to get the paykey. Then I redirect the user to paypal and the payment is done (and charged).
Am I missing something?
List<PaymentReceiver> receiverList = setReceiversSingleProject(order);
Element root = new Element("PayRequest");
root.addNamespaceDeclaration("ns2", "http://svcs.paypal.com/types/ap");
// requestEnvelope and errorLanguage
Element requestEnvelopeElement = new Element("requestEnvelope");
Element errorLanguageElement = new Element("errorLanguage");
errorLanguageElement.appendChild(errorLanguage);
requestEnvelopeElement.appendChild(errorLanguageElement);
root.appendChild(requestEnvelopeElement);
// cancelUrl
Element cancelUrlElement = new Element("cancelUrl");
cancelUrlElement.appendChild(themeDisplay.getPortalURL()+"/basket");
root.appendChild(cancelUrlElement);
// actionType
Element actionTypeElement = new Element("actionType");
actionTypeElement.appendChild("CREATE");
root.appendChild(actionTypeElement);
// currencyCode
Element currencyCodeElement = new Element("currencyCode");
String projectCurrency = order.getMainProject().getCurrency();
Currency currency = CurrencyLocalServiceUtil.getCurrency(projectCurrency);
currencyCodeElement.appendChild(currency.getPaypalCode());
root.appendChild(currencyCodeElement);
// receiverList
Element receiverListElement = new Element("receiverList");
for (PaymentReceiver receiver : receiverList) {
Element receiverElement = new Element("receiver");
Element amountElement = new Element("amount");
amountElement.appendChild(String.valueOf(receiver.getAmount()));
Element emailElement = new Element("email");
emailElement.appendChild(receiver.getEmail());
Element primaryElement = new Element("primary");
primaryElement.appendChild(receiver.isPrimary()?"true":"false");
receiverElement.appendChild(amountElement);
receiverElement.appendChild(emailElement);
receiverElement.appendChild(primaryElement);
receiverListElement.appendChild(receiverElement);
}
root.appendChild(receiverListElement);
// returnUrl
Element returnUrlElement = new Element("returnUrl");
returnUrlElement.appendChild(returnURL);
root.appendChild(returnUrlElement);
// notifyUrl
Element notifyUrlElement = new Element("ipnNotificationUrl");
notifyUrlElement.appendChild(notifyURL);
root.appendChild(notifyUrlElement);
// Create document object
Document doc = new Document(root);
String result = doc.toXML();
return result;

Related

Google calendar event, conference details are not being set

I'm trying to create the Google Calendar event with the conference(Google Meet) using Java SDK V3. The event is getting created but the conference details are not being set. Not sure what's missing
Create request:
Calendar service = new Calendar
.Builder(GoogleNetHttpTransport.newTrustedTransport(),
getDefaultInstance(),
new HttpCredentialsAdapter(googleCalendarCredentials()))
.setApplicationName(APPLICATION_NAME)
.build();
Event event = new Event();
event.setStart(new EventDateTime().setDateTime(new DateTime(currentTimeMillis())));
event.setEnd(new EventDateTime().setDateTime(new DateTime(currentTimeMillis() + 10000000)));
ConferenceData conferenceData = new ConferenceData();
conferenceData.setCreateRequest(
new CreateConferenceRequest()
.setConferenceSolutionKey(
new ConferenceSolutionKey()
.setType("hangoutsMeet")));
event.setConferenceData(conferenceData);
service.events().insert("primary", event).execute();
Get Request:
Events events = service.events()
.list("primary")
.execute();
List<Event> items = events.getItems();
if (items.isEmpty()) {
System.out.println("No upcoming events found.");
} else {
System.out.println("Upcoming events");
for (Event eventRs : items) {
System.out.printf("%s\n", eventRs.getConferenceData().getConferenceId());
}
}
Getting eventRs.getConferenceData() as null.
If you check the documentaiton on Event.insert you will see that you need to set the option parameter conferenceDataVersion inorder to enable it to set the conference data.
Version 0 assumes no conference data support and ignores conference data in the event's body. Version 1 enables support for copying of ConferenceData

How to react on newly created Appointments?

I am looking for a way to get a delta of Appointments. Basically what I want is to react on newly created Appointments.
To get newly created / unread messages there is a SearchFilter in the java ews api that I use. Unfortunately AppointmentSchema does not provide any fitting Enum for the filter.
new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
I get the Appointments like:
CalendarFolder calendarFolder = CalendarFolder.bind(service, WellKnownFolderName.Calendar, new PropertySet());
var result = calendarFolder.findAppointments(cView);
so back to my question. How can I notice if someone invited me to a new Appointment or an email with a new Appointment invitation?
I have already found a solution, luckily. MeetingRequest is the Item I am looking for.
FindItemsResults<Item> result = service.findItems(new FolderId(WellKnownFolderName.Inbox, new Mailbox(getCredentials())), getUnreadEmailFilter(), new ItemView(10));
result.forEach(n -> {
if (n instanceof MeetingRequest) {
System.out.println("New Appointment - MeetingRequest found!");
MeetingRequest req = (MeetingRequest) n;
req.accept(true);
}
}

Large USN value in Evernote initial sync

I am trying to sync an evernote account using Java program, below is the code sample for it
NoteStoreClient noteStoreClient = clientFactory.createNoteStoreClient();
SyncChunk syncChunk = noteStoreClient.getSyncChunk(0, 200, true);
while (true) {
List<Note> noteListforCurrentChunk = syncChunk.getNotes();
//Sync to DB
syncChunk = noteStoreClient.getSyncChunk(syncChunk.getChunkHighUSN(), 200, true);
if (syncChunk.getChunkHighUSN() == syncChunk.getUpdateCount()) {
return;
}
}
The first call to syncChunk.getChunkHighUSN() returns 1187 for my user, which results in no notes being retrieved. This is happening to some accounts only
Can anyone help on this ?
Here's some quote on USN from the doc.
The USNs within an account start at “1” (for the first object created in the account) and then increase
monotonically every time an object is created, modified, or deleted. The server keeps track of the
“update count” for each account, which is identical to the highest USN that has been assigned.
So, the higher number of USN doesn't always mean you have many notes. It just indicates that the user has done some operations on its account.
I had to create a filter to make it working. Now i am able to retrieve all the notes under this notebook
SyncChunkFilter filter = new SyncChunkFilter();
filter.setIncludeNotes(true);
NoteStoreClient noteStoreClient = clientFactory.createNoteStoreClient();
SyncChunk syncChunk = noteStoreClient.getFilteredSyncChunk(0, 200, filter);
while (true) {
List<Note> noteListforCurrentChunk = syncChunk.getNotes();
//Sync to DB
syncChunk = noteStoreClient.getFilteredSyncChunk(syncChunk.getChunkHighUSN(), 200, filter);
if (syncChunk.getChunkHighUSN() == syncChunk.getUpdateCount()) {
return;
}
}

neo4j Java beginner. Cypher Execution Engine

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/

Payment works but the user never knows if it was a subscription or one time payment on the Paypal page

So I've integrated the Paypal in my payment flow and this is what happens:
User comes on the page. Clicks the Payment Button
User Is first redirected to a page which calls SetExpressCheckout and is redirected to Paypal. (He is to be billed one time for say, $77 and then every month for 1 year for the same amount. Hence I don't set the initial amount, instead deduct it directly.)
On returning, he clicks the confirm button and one time payment is deducted using DoExpressCheckout and billing profile is created.
Everything works fine. I get the payment every month. The user is not billed twice at the start.
The PROBLEM: When the user was redirected to Paypal, he only sees the ITEM NAME and DESCRIPTION I've set. I.e. There is not description from Paypal whether the transaction is one time or subscription like there is when you use a simple subscription button for payment. Paypal only mentions the amount but not the type of transaction.
NVPEncoder encoder = new NVPEncoder();
encoder.add("METHOD","SetExpressCheckout");
encoder.add("RETURNURL",returnURL);
encoder.add("CANCELURL",cancelURL);
encoder.add("CURRENCYCODE","USD");
encoder.add("AMT",amt);
encoder.add("BILLINGPERIOD", "Month");
encoder.add("BILLINGFREQUENCY", "1");
encoder.add("PROFILESTARTDATE",dateFormatGmt.format(new Date()));
encoder.add("L_BILLINGTYPE0", "RecurringPayments");
encoder.add("L_BILLINGAGREEMENTDESCRIPTION0",package_name);
encoder.add("L_NAME0",package_name);
encoder.add("L_AMT0",amt);
encoder.add("L_QTY0","1");
String strNVPRequest = encoder.encode();
String ppresponse = (String) caller.call(strNVPRequest);
NVPDecoder resultValues = new NVPDecoder();
resultValues.decode(ppresponse);
String strAck = resultValues.get("ACK");
if (strAck !=null && !(strAck.equals("Success") ||
strAck.equals("SuccessWithWarning"))) {
response.sendRedirect("APIError.jsp");
} else {
response.sendRedirect(redirectUrl);
}
Are you including L_BILLINGTYPE0=RecurringPayments?
This is what should change the wording on the PayPal landing page.
To recap; call the following API calls, with (at least) the following parameters:
SetExpressCheckout:
$nvps = array();
$nvps["VERSION"] = "80.0";
$nvps["METHOD"] = "SetExpressCheckout";
$nvps["PAYMENTREQUEST_0_PAYMENTACTION"] = "Sale";
$nvps["PAYMENTREQUEST_0_AMT"] = "1.00";
$nvps["PAYMENTREQUEST_0_CURRENCYCODE"] = "GBP";
$nvps["PAYMENTREQUEST_0_ITEMAMT"] = "1.00";
$nvps["L_BILLINGTYPE0"] = 'RecurringPayments';
$nvps["L_BILLINGAGREEMENTDESCRIPTION0"] = "the subscription";
$nvps["L_PAYMENTREQUEST_0_NUMBER0"] = 1;
$nvps["L_PAYMENTREQUEST_0_NAME0"]= "subscription";
$nvps["L_PAYMENTREQUEST_0_AMT0"]= 1.00;
$nvps["L_PAYMENTREQUEST_0_QTY0"]= 1;
And CreateRecurringPaymentsProfile with:
$nvps["PROFILESTARTDATE"] = "2011-07-08T17:40:00Z";
$nvps["BILLINGPERIOD"] = "Month";
$nvps["BILLINGFREQUENCY"] = "1";
$nvps["AMT"] = "1.00";
$nvps["CURRENCYCODE"] = "GBP";
$nvps["DESC"] = "the subscription";

Categories