I've got google wallet for digital goods working fine for fixed price items. However, I would like to sell user priced items or subscriptions (i.e., pay what you want or can). So the user would enter the price they want to pay.
However, I cannot seem to find any way to do this with google wallet for digital goods. Any ideas or tips?
The key item is for the JWT to be generated server-side.
A trivial example is here
Pls. note that I just mocked this so I'm not doing a lot of validations to user input - so please be gentle - it's just for reference showing how you can accomplish things.
Also this says nothing of Google's policy (check with them about donations)....
In summary what the sample does:
Allow user to provide some value in a standard <input />
Send data to server via Ajax (e.g. jQuery $.post) and generate the necessary JWT based on user input/s
If JWT is generated successfully, call buy (google.payments.inapp.buy) and supply it the server generated value (the JWT) returned from #2
E.g.
$(function () {
$("#donateForm").on("submit", function (e) {
e.preventDefault();
var data = $("#donateForm").serialize();
$.post("ajaxhandler.ashx", data) //send to server to generate JWT
.done(function (d) { //d is the JWT in this sample
google.payments.inapp.buy({
"parameters": {},
"jwt": d, //d goes here
"success": function (result) {
//handle Wallet success as you deem fit
},
"failure": function (result) {
//handle Wallet failures as you deem fit
}
}
);
}).fail(function (f) {
//handle ajax failure as you deem fit
}).always(function (a) {
//handle as you deem fit
});
........
Hth...
Related
I have a simple ToDo app using React frontend, Nodejs/Express API backend, and MySQL DB. My tasks DB has a userId column which pulls the user.sub value on the frontend before sending the task to the backend and creating the DB entry.
Next, I want users to be able to see only their own tasks as identified by the userId column - to do this, I want to pull the user.sub value of the current logged-in user and dynamically insert it into my backend SQL query.
Example:
Task.getAll = (userId, result) => {
let query = `SELECT * FROM tasks WHERE userId LIKE '${userId}'`;
sql.query(query, (err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
console.log("tasks: ", res);
result(null, res);
});
};
If I hardcode an existing auth0 user ID (“auth0|123456789…”) into the statement above, it successfully filters tasks based on ID - so the logic seems sound. I just need to be able to pull the user.sub value, which I have not been able to figure out in the backend. I have been following this quickstart document - https://auth0.com/docs/get-started/architecture-scenarios/spa-api/api-implementation-nodejs:
Determine the User Identity The express-jwt middleware which is used to validate the JWT, also sets the req.user with the information
contained in the JWT. If you want to use the sub claim to identify the
user uniquely, you can simply use req.user.sub.
…This sounds like what I want to achieve, but I can’t figure out how to actually do this in practice. How exactly can I pull the user.sub value from the checkJwt middleware?
I am currently working with the plivo api to build an ivr, however, I have used all the recommendations given by the documentation and so far I can not establish a successful connection within the conference calls in the application, below I attach the code that is involved in the conference function.
getDialConnecting(numberFrom, numberTo, route){
let ivr = new Ivr();
let client = ivr.getClient();
client.calls.create(
`${numberFrom}`,
`${numberTo}`,
`${process.env.HOST}${route}`,
{
answerMethod: "POST"
},
).then(function(response){
console.log(response);
}, function(err){
console.log(err);
});
this function is called each time I make a conference call and enter the following parameters
I am currently working with the plivo api to build an ivr, however, I have used all the recommendations given by the documentation and so far I can not establish a successful connection within the conference calls in the application, below I attach the code that is involved in the conference function.
call.getDialConnecting(`${incomingNumber}`, `${incomingNumberTransmitter}`, 'conference');
in addition this is the path that is performing the handling of the function that accepts the call
const ivrGetConference = route.post('/voice/conference', call.callRequestConfirmed);
My name is Mohammed Huzaif, and I work at Plivo as a Product Evangelist.
From the information shared, I'm unable to determine the error you may have received on your end or the documents utilised.
However, you can follow the below steps to build an IVR.
First, we'll create our IVR, To do so, follow the directions in this documentation.
Once the IVR system is developed, we will make a call to the destination number by using the URL generated in above step.
To make a call, use the below code.
Note: Replace the placeholders "from": with the caller_id, "to": Destination number, and "answer_url": the url generated in above step.
var plivo = require('plivo');
(function main() {
'use strict';
var client = new plivo.Client("<auth_id>","<auth_token>"); // https://console.plivo.com/dashboard/
client.calls.create(
"+14151234567", // from
"+15671234567", // to
"https://s3.amazonaws.com/static.plivo.com/answer.xml", // answer url
{
answerMethod: "POST",
},
).then(function (response) {
console.log(response);
}, function (err) {
console.error(err);
});})();
In case, if you still need any assistance, feel free to reach out to our support-team.
As per the documentation here & the github source code here, I have cloned the application, its working perfectly.
Suppose if my sales person having some extension then how can I give that extension in this script. Normally, using senddigit I can pass the extension in twilio but I dont know how to implement that with this salesNumber.
twilioClient.createCall(salesNumber, phoneNumber, headersHost)
.then((result) => {
response.send({message: result});
})
.catch((error) => {
response.status(500).send(error);
});
Please some one help on this.
I think you're looking at the wrong code snippet here. The code above doesn't call the Twilio client directly. Instead, it calls the helper function from this file to initiate the call.
Once the user picks up, they will be connected to the sales person via TwiML in this function:
voiceResponse: (salesNumber, Voice = VoiceResponse) => {
let twimlResponse = new Voice();
twimlResponse.say('Thanks for contacting our sales department. Our ' +
'next available representative will take your call. ',
{ voice: 'alice' });
twimlResponse.dial(salesNumber);
return twimlResponse.toString();
}
In this function, you'll be able to send digits along as mentioned here.
I'm trying to figure out how to pass in a "trial" period, or custom "start date" for a subscription. I have:
paypal.Buttons({
createSubscription: function(data, actions) {
return actions.subscription.create({
'plan_id': window.my_config.paypal_sub_ids[window.my_config["period"]],
'custom_id': $('#Email').val() + "----" + window.my_config["period"]
});
},
onApprove: function(data, actions) {
$('#AJAXloadingWrapper').show();
console.log({ data: data, actions: actions });
// all the rest is done on the server
},
onError: function (err) {
// Show an error page here, when an error occurs
console.log("ERROR")
console.dir(err);
}
}).render('#paypalWrapper');
This works fine. The problem I'm having, is that what I want to do is offer a unique number of free days to a user. A use case is that a user is already a paid member (one off payments), and they want to setup a subscription with us. So obviously you don't want the subscription to start until their current date has expired.
Is there a way to pass this in with the JS SDK? Or is it going to be a PITA where I have to create a custom price plan for that user, with the correct number of days set?
UPDATE: Alternatively, is there a way to "clone" an existing subscription plan, and then tweak the trial_days server side, ready to return to the front end for the JS side of things?
You can get a plan's details and create a new modified plan based on it.
The API call is https://developer.paypal.com/docs/api/subscriptions/v1/#plans_get
I have been staring at this for hours and can't find a solution and that is even though by all suggestions it SHOULD be quite easy - https://learn.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-proactive-messages.
I have created a simple code which will "register" the user and save their data in my cosmosDatabse on Azure. That works perfectly.
//ON "register" SAVE USER DATA AND SAY REGISTERED MESSAGE
bot.dialog('adhocDialog', function(session, args) {
var savedAddress = session.message.address;
session.userData.savedAddress = savedAddress;
//REGISTERED MESSAGE
session.endDialog("*Congratulations! You are now registered in our network! (goldmedal)*");
})
.triggerAction({
matches: /^register$/i
})
But how can I then access that specific user and send him a message if, say, a condition is met? (in fact on HTTP request)
I am fairly certain we have to write the conversation ID or user ID somewhere. The question is where?
function startProactiveDialog(address) {
bot.beginDialog(address, "A notification!");
}
This is how simple I think it should be. But where do you specify the user then?
You've saved the address of the user inside of your database by saving it to session.userData.savedAddress. When the event triggers, perform a query to your database that checks for the users that meet two criteria.
They're registered to listen for the event
Their address has been saved inside of the database.
In your case, you can save a property to the session.userData object, a property that lists which events they're listening for. If you just need to send a message to the user, then you can simply use bot.loadSession(savedAddress) to ping the user.
Edit:
So instead of looking specifically by user ID, you should send a query to your CosmosDB that looks for entries that have a "listen-to" Boolean-type flag corresponding to the event.
You're not worrying about the user ID at first, you're just retrieving all entries with a query that would (broadly speaking) look like this:
SELECT * FROM BotState WHERE data LIKE 'listenForEvent=1.
So to setup your session.userData so that the above theoretical query would work, you would need to modify that snippet of code in your question to something like the following:
bot.dialog('adhocDialog', function(session, args) {
var savedAddress = session.message.address;
session.userData.savedAddress = savedAddress;
session.userData.listenForEvent = 1 // Our property we're going to look for.
session.endDialog("*Congratulations! You are now registered in our network! (goldmedal)*");
})
.triggerAction({
matches: /^register$/i
})
Actually, the savedAddress should be an instance of IAddress, and also, the function loadSession(address: IAddress, callback: (err: Error, session: Session) => void): void; and address(adr: IAddress): Message; under Message class all require IAddress as the parameter.
So first of all, you should save the entire address json object in cosmosDB for later using.
As botbuilder for Node.js is built on Restify or Express, you can build an addition route for your user to trigger and send proactive messages. The work flow could be following:
Guide user to register & Save the user's address object with the account mapping in your DB
Create a Route in Restify or Expressjs for trigger the proactive message:
server.get('/api/CustomWebApi', (req, res, next) => {
//find the user's address in your DB as `savedAddress`
var msg = new builder.Message().address(savedAddress);
msg.text('Hello, this is a notification');
bot.send(msg);
res.send('triggered');
next();
}
);
or if you want to leverage loadSession
server.get('/api/CustomWebApi', function (req, res, next) {
bot.loadSession(savedAddress, (err, session) => {
if (!err) {
session.send('Hello, this is a notification')
session.endConversation();
}
})
res.send('triggered');
next();
});
I created a users.json file, to which I save all the users. It works the way I need it to. I guess database would be better, but I don't really have a clue where to begin with that. Database is a whole new chapter I have not encountered yet, so it doesn't make sense to work on it when the project needs are resolved.