java paypal webhook controller to handle event of payment - java

i need to implement webhook controller to handle complete payment event so how can i handle or subscribe.
`public IActionResult Webhook()
{
// The APIContext object can contain an optional override for the trusted certificate.
var apiContext = PayPalConfiguration.GetAPIContext();
// Get the received request's headers
var requestheaders = HttpContext.Request.Headers;
// Get the received request's body
var requestBody = string.Empty;
using (var reader = new System.IO.StreamReader(HttpContext.Request.Body))
{
requestBody = reader.ReadToEnd();
}
dynamic jsonBody = JObject.Parse(requestBody);
string webhookId = jsonBody.id;
var ev = WebhookEvent.Get(apiContext, webhookId);
// We have all the information the SDK needs, so perform the validation.
// Note: at least on Sandbox environment this returns false.
// var isValid = WebhookEvent.ValidateReceivedEvent(apiContext, ToNameValueCollection(requestheaders), requestBody, webhookId);
switch (ev.event_type)
{
case "PAYMENT.CAPTURE.COMPLETED":
// Handle payment completed
break;
case "PAYMENT.CAPTURE.DENIED":
// Handle payment denied
break;
// Handle other webhooks
default:
break;
}
return new HttpStatusCodeResult(200);
}
this is javascript example i got but same as i want to handler implementation in java.and which parameters are needed when controller getting hit.

For PayPal Subscriptions, the list of Webhook event names is here: https://developer.paypal.com/docs/api-basics/notifications/webhooks/event-names/#subscriptions , and in particular the one you would want is PAYMENT.SALE.COMPLETED (not ".CAPTURE.")
You may find the information here helpful: https://stackoverflow.com/a/65139331/2069605

Related

Get expiry date from firebase token (JOSE header "typ" (type) "JWT" not allowed)

I need to extract the expiry date of firebase tokens. How can I extract the "exp" from the token in java?
I tried to use code from https://connect2id.com/products/nimbus-jose-jwt/examples/validating-jwt-access-tokens using com.nimbusds:nimbus-jose-jwt:9.23 but it fails:
String accessToken = "...";
// Create a JWT processor for the access tokens
ConfigurableJWTProcessor<SecurityContext> jwtProcessor =
new DefaultJWTProcessor<>();
// Set the required "typ" header "at+jwt" for access tokens issued by the
// Connect2id server, may not be set by other servers
jwtProcessor.setJWSTypeVerifier(
new DefaultJOSEObjectTypeVerifier<>(new JOSEObjectType("at+jwt")));
// The public RSA keys to validate the signatures will be sourced from the
// OAuth 2.0 server's JWK set, published at a well-known URL. The RemoteJWKSet
// object caches the retrieved keys to speed up subsequent look-ups and can
// also handle key-rollover
// I changed it to what I think should work for firebase, but it doesn't seem to matter what I put here:
JWKSource<SecurityContext> keySource =
new RemoteJWKSet<>(new URL("https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken#system.gserviceaccount.com"));
// The expected JWS algorithm of the access tokens (agreed out-of-band)
JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
// Configure the JWT processor with a key selector to feed matching public
// RSA keys sourced from the JWK set URL
JWSKeySelector<SecurityContext> keySelector =
new JWSVerificationKeySelector<>(expectedJWSAlg, keySource);
jwtProcessor.setJWSKeySelector(keySelector);
// Set the required JWT claims for access tokens issued by the Connect2id
// server, may differ with other servers
jwtProcessor.setJWTClaimsSetVerifier(new DefaultJWTClaimsVerifier(
null,
new HashSet<>(Arrays.asList("exp"))));
// Process the token
SecurityContext ctx = null; // optional context parameter, not required here
JWTClaimsSet claimsSet = jwtProcessor.process(accessToken, ctx);
// Print out the token claims set
System.out.println(claimsSet.toJSONObject());
I get this error:
JOSE header "typ" (type) "JWT" not allowed
com.nimbusds.jose.proc.BadJOSEException: JOSE header "typ" (type) "JWT" not allowed
at com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier.verify(DefaultJOSEObjectTypeVerifier.java:149)
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:341)
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:303)
at com.nimbusds.jwt.proc.DefaultJWTProcessor.process(DefaultJWTProcessor.java:294)

How to obtain `ApproximateReceiveCount` from an SQS message

I'm using Amazon SQS. My goal is to read ApproximateReceiveCount attribute from ReceiveMessage API action using the Java SDK (v2.10.4, Java 11).
I tried the following code, but message.attributes() doesn't contain the required key:
String getApproximateReceiveCount() {
var receiveMessageRequest = ReceiveMessageRequest.builder()
.queueUrl("https://sqs.eu-west-1.amazonaws.com/012345678910/my-example-queue")
.build();
var sqsClient = SqsClient.builder().endpointOverride(URI.create("http://localhost:4576")).build();
var response = sqsClient.receiveMessage(receiveMessageRequest);
var message = response.messages().get(0);
return message.attributes().get(MessageSystemAttributeName.APPROXIMATE_RECEIVE_COUNT);
}
How to go about receiving an entry for MessageSystemAttributeName.APPROXIMATE_RECEIVE_COUNT key, in this map?
As per the documentation page to ReceiveMessage which you linked, there is a parameter called AttributeName.N described as
A list of attributes that need to be returned along with each message. These attributes include:
[...]
ApproximateReceiveCount – Returns the number of times a message has been received from the queue but not deleted.
Therefore you need to ask for the attribute in the request, for it to be available in the response. To do that use ReceiveMessageRequestBuilder.attributeNamesWithStrings() method like so:
String getApproximateReceiveCount() {
var receiveMessageRequest = ReceiveMessageRequest.builder()
.queueUrl("https://sqs.eu-west-1.amazonaws.com/012345678910/my-example-queue")
.attributeNamesWithStrings(MessageSystemAttributeName.APPROXIMATE_RECEIVE_COUNT.toString())
.build();
var sqsClient = SqsClient.builder().endpointOverride(URI.create("http://localhost:4576")).build();
var response = sqsClient.receiveMessage(receiveMessageRequest);
var message = response.messages().get(0);
return message.attributes().get(MessageSystemAttributeName.APPROXIMATE_RECEIVE_COUNT);
}
Note that there are two similarly named methods, which you can't use:
.attributeNames() - the parameter enum doesn't list the required key,
.messageAttributeNames() - corresponds to attributes sent along with the message body.

Can I use the ListUsers API to query a Cognito User Pool by a user's uuid?

The docs for cognito user pools can be found here:
http://docs.aws.amazon.com/cognito/latest/developerguide/how-to-manage-user-accounts.html
In this they do not say whether you can query users by the automatically generated sub attribute, which is a uuid. It explicitly says you can't search for users by custom attributes, but sub/uuid is not a custom attribute. Weirdly though, in the list of searchable attributes sub/uuid is not one of them. Surely though you can look up users by their UUID, how would this be done though??
You know, I have used COgnito but never needed to look up via sub (or other params other than the username). I looked into it because surely you can, but it is not very clear (like a lot of their documentation). Here is what I saw that you could try... hope it helps man.
// the imported ListUsersResult is...
import com.amazonaws.services.cognitoidp.model.ListUsersRequest;
import com.amazonaws.services.cognitoidp.model.ListUsersResult;
// class var
protected final AWSCognitoIdentityProviderClient identityUserPoolProviderClient;
// omitted stuff...
// initialize the Cognito Provider client. This is used to talk to the user pool
identityUserPoolProviderClient = new AWSCognitoIdentityProviderClient(new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY)); // creds are loaded via variables that are supplied to my program dynamically
identityUserPoolProviderClient.setRegion(RegionUtils.getRegion(USER_POOL_REGION)); // var loaded
// ...some code omitted
ListUsersRequest listUsersRequest = new ListUsersRequest();
listUsersRequest.withUserPoolId(USER_POOL_ID); // id of the userpool, look this up in Cognito console
listUsersRequest.withFilter("sub=xyz"); // i THINK this is how the Filter works... the documentation is terribad
// get the results
ListUsersResult result = identityUserPoolProviderClient.listUsers(listUsersRequest);
List<UserType> userTypeList = result.getUsers();
// loop through them
for (UserType userType : userTypeList) {
List<AttributeType> attributeList = userType.getAttributes();
for (AttributeType attribute : attributeList) {
String attName = attribute.getName();
String attValue = attribute.getValue();
System.out.println(attName + ": " + attValue);
}
}
If you have the username you could get the user like this
// build the request
AdminGetUserRequest idRequest = new AdminGetUserRequest();
idRequest.withUserPoolId(USER_POOL_ID);
idRequest.withUsername(username);
// call cognito for the result
AdminGetUserResult result = identityUserPoolProviderClient.adminGetUser(idRequest);
// loop through results

How to get SoapUI request and response XML in java

I'm using the SoapUI API as part of an existing java project.
The application should save the request and response XML in an specific report file.
I wonder if it's possible to get those requests and responses via the API.
The method invoking the TestCaseRunner looks like this
protected void checkTestCase(TestCase testCase) {
TestCaseRunner tr = testCase.run(null, false);
for (TestStepResult tcr : tr.getResults()) {
String status = tcr.getStatus();
String time = tcr.getTimeTaken() + "ms";
/* How to get XML messages?
* String request =
* String response =
*/
}
}
Depending on exactly what kind of test steps you have they might be an instance of a MessageExchange. Casting the TestStepResult to a MessageExchange and calling getRequestContent / getResponseContent might do the trick.
String request = ((MessageExchange)tcr).getRequestContent();
String response = ((MessageExchange)tcr).getResponseContent();
I have used the following way to get the response from the API CAll performed:
runner = testRunner.runTestStepByName("Your Test Case name");
// Here we take the response in ms of the API call
timeTaken = runner.response.timeTaken;
// here we get the HTTP response code.
responseCode = runner.getResponseHeaders()."#status#";
// here we get the response content
String response = runner.getResponseContent();
// here we get the API call endpoint -> in case you need to print it out.
String endPoint = runner.getEndpoint();

AMF client in Java

I am using BlazeDS java client to get info from this page.
This page has a form in the middle that when you select a type, the location combo on the button gets updated.
I am trying to use BlazeDS to get those values in java.
I have been using Charles web proxy to debug, and this are the screenshots from the request and the response:
My code so far is the following:
// Create the AMF connection.
AMFConnection amfConnection = new AMFConnection();
// Connect to the remote url.
String url = "http://orlandoinfo.com/flex2gateway/";
try
{
amfConnection.connect(url);
}
catch (ClientStatusException cse)
{
System.out.println(cse);
return;
}
// Make a remoting call and retrieve the result.
try
{
// amfConnection.registerAlias("flex.messaging.io.ArrayCollection", "flex.messaging.io.ArrayCollection");
amfConnection.call("ColdFusion.getLocations", new Object[] {"consumer", "attractions", "ATTR"});
}
catch (ClientStatusException cse)
{
System.out.println(cse);
}
catch (ServerStatusException sse)
{
System.out.println(sse);
}
// Close the connection.
amfConnection.close();
When I run it I get a:
ServerStatusException
data: ASObject(15401342){message=Unable to find source to invoke, rootCause=null, details=null, code=Server.Processing}
HttpResponseInfo: HttpResponseInfo
code: 200
message: OK
Can anyone spot what's wrong?
Thanks for reading!
I ended up using Charles Web Proxy. Sniffing AMF parameters and running my code with -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888
I compare both calls and modify to look alike.
The working code looks like this:
String url = "http://www.theGateWayurl.com";
// Generates the connection to the amf gateway.
AMFConnection amfConnection = new AMFConnection();
// Must register the class that this library will use to load the
// AMF object information.
// The library will read AMF object variables and use setters from
// the java bean stated in this line.
AMFConnection.registerAlias("", new LabelData().getClass().getName());
try {
// Do the connection.
amfConnection.connect(url);
// This page requires a certain headers to function.
// The Content-type is used to sniff with Charles Web Proxy.
amfConnection.addHttpRequestHeader("Content-type", "application/x-amf");
// The Referer is used by the webpage to allow gathering information.
amfConnection.addHttpRequestHeader("Referer", "http://orlandoinfo.com/ws/b2c/sitesearch/customtags/comSearch.swf");
// The rest of the HTTP POST sent by this library is wrapped
// inside a RemotingMessage.
// Prepare the msg to send.
RemotingMessage msg = new RemotingMessage();
// The method called in the server.
msg.setOperation("getLocations");
// Where the request came from. Similar to referer.
msg.setSource("ws.b2c.sitesearch.components.myService");
// The destination is a needed parameter.
msg.setDestination("ColdFusion");
// Create the body with the parameters needed to call the
// operation set with setOperation()
msg.setBody(new Object[] {"consumer", "attractions"});
// This is needed but not used.
msg.setMessageId("xxxxxxxxxx");
// Send the msg.
AcknowledgeMessage reply = (AcknowledgeMessage) amfConnection.call("null", msg);
// Parse the reply from the server.
ArrayCollection body = (ArrayCollection) reply.getBody();
for (Object obj : body) {
LabelData location = (LabelData) obj;
// Do something with the info.
}
} catch (ClientStatusException cse) {
// Do something with the exception.
} catch (ServerStatusException sse) {
// Do something with the exception.
} finally {
amfConnection.close();
}
The LabelData is just a java bean with with two vars: Data and Label.
I tried to comment every line for a better understanding.
Take into account what Stu mention in previous comments about crossdomain.xml to see if you have the rights to do this kind of things.

Categories