I have used SOAP API to create Embedded signing. I am using template (CreateEnvelopeFromTemplates) to create envelope. I have added a payment field on template which works fine if I send envelope request from docusign website. I get a popup to enter payment information. BUT when I am sending the same template from API then Payment functionality is not working. Payment field is appearing as number.
screenshot
Here is my code
public class DS_Recipe_Signer_View_Controller {
// Embedded signing of an envelope
// Copyright (c) 2016 DocuSign, Inc.
// LICENSE: The MIT License, see https://opensource.org/licenses/MIT
// SETTINGS
// Private static string integration_key = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
// Private static string account_id = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
Private static string integration_key = 'XXXXXXXXXX-98333677e8bd';
Private static string account_id = 'XXXXXXXXXXX-5f66c17b7f9f';
// NOTE: You MUST use the long form of the account id. It's has 32 digits
// with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
// This version of the account id is shown in the APIs and Connects section
// of your DocuSign Administration tool
Public string signer_email {get;set;} // Required
Public string signer_name {get;set;} // Required
Public string email_message {get;set;} // Required
Public string signer_user_id {get;set;} // Required for embedded signing
Public string signer_return_url {get;set;} // Required. Where DS redirects to after the signing ceremony
Public string output {get;set;}
Public string envelope_id {get;set;}
Public string signer_view_url {get;set;} // Redirect to this url
Public string error_code {get;set;} // Null means no error
Public string error_message {get;set;}
// Using Legacy authentication via an SFDC Named Credential
Private static string ds_server = 'callout:DocuSign_Legacy_Demo/api/3.0/dsapi.asmx';
// If you choose to not use a named credential:
//Private static string ds_server = 'https://requestb.in/119qunn1';
//Private static string ds_server ='https://demo.docusign.net/api/3.0/dsapi.asmx';
Private static string trace_value = 'SFDC_002_SOAP_embedded_signing'; // Used for tracing API calls
Private static string trace_key = 'X-ray';
Private DocuSignTK.APIServiceSoap api_sender = new DocuSignTK.APIServiceSoap();
Public DS_Recipe_Signer_View_Controller(){}
Public void send(){
configure_sender();
send_envelope();
embedded_signing();
if (no_error()) {
output = '<p>The envelope was sent, Envelope ID: ' + envelope_id + '</p>';
output += '<p></p><p>Signer: ' + signer_name + ' <' + signer_email + '></p>';
output += '<p><b>To sign the envelope, redirect the user to the <a href = "' +
signer_view_url + '" target="_blank">DocuSign Signing Ceremony</a></b></p>';
output += '<p>The redirect address is ' + signer_view_url + '</p>';
output += '<p><b>Note:</b> the Signing Ceremony url can only be used for a couple of minutes after ' +
'it has been created. Do NOT store the url for later use. Instead, ' +
'generate the URL immediately before you redirect the user\'s browser.</p>';
output += '<p>After the signer has completed the signing ceremony, his ' +
'browser will be redirected back to your app with some query fields added. Example: </p>' +
'<p>http://www.foo.com/?event=signing_complete</p>';
} else {
output = '<h3>Problem</h3><p>' + error_message + '</p>';
}
}
Private void configure_sender(){
api_sender.endpoint_x = ds_server;
api_sender.inputHttpHeaders_x = new Map<String, String>();
String auth = '<DocuSignCredentials><Username>{!$Credential.Username}</Username>'
+ '<Password>{!$Credential.Password}</Password>'
+ '<IntegratorKey>' + integration_key + '</IntegratorKey></DocuSignCredentials>';
api_sender.inputHttpHeaders_x.put('X-DocuSign-Authentication', auth);
api_sender.inputHttpHeaders_x.put(trace_key, trace_value);
}
Private void embedded_signing() {
// Obtains the embedded Signing Ceremony URL for an envelope's recipient (the signer).
// To use embedded signing:
// 1. The signer must have been added to the envelope as a "captive signer"
// 2. You need the following values:
// 1. EnvelopeID
// 2. Signer's Email that was provided when the signer was added to the envelope.
// 3. Signer's name (UserName field)
// 4. The Signer's User ID (client id) within your app. Must uniquely identify the signer.
// 3. You also need to create an "Assertion" object where you provide information on how
// your app authenticated the signer. This information is stored by DocuSign so you can
// later use the data in case of a dispute.
// Incoming variables used:
// envelope_id, signer_user_id, signer_email, signer_name
// Maintaining state: when DocuSign redirects back to your app after the signing ceremony
// ended, how does your app know what is going on? You can include additional query parameters
// in the signer_return_url that you supply. Eg the recipient ID, envelope ID, etc.
// You can include your app's sessionID. You can use the cookie system to store either
// specific information or your stack's session id for your app.
// Step 1. Create the assertion
DocuSignTK.RequestRecipientTokenAuthenticationAssertion assertion =
new DocuSignTK.RequestRecipientTokenAuthenticationAssertion();
assertion.AssertionID = '1'; // A unique identifier of the authentication
// event executed by your application.
assertion.AuthenticationInstant = Datetime.now(); // The date/time that the end-user was authenticated.
assertion.AuthenticationMethod = 'Password'; // How did your app authenticate the signer?
// Options: Password, Email, PaperDocuments, HTTPBasicAuth, SSLMutualAuth, X509Certificate, Kerberos,
// SingleSignOn_CASiteminder, SingleSignOn_InfoCard, SingleSignOn_MicrosoftActiveDirectory, SingleSignOn_Passport,
// SingleSignOn_SAML, SingleSignOn_Other, Smartcard, RSASecureID, Biometric, None, KnowledgeBasedAuth
assertion.SecurityDomain = 'DS_Recipe_Signer_View_Controller'; // The "domain" (app, sso system, etc)
// to which the user authenticated
// Step 2. Create the redirect URLs for the different outcomes of the Signing Ceremony
DocuSignTK.RequestRecipientTokenClientURLs urls = new DocuSignTK.RequestRecipientTokenClientURLs();
String return_url_base = signer_return_url;
// The supplied url may already include one or more query parameters. In that case, we're appending
// one more query parameters. Otherwiser, we're adding the first set of query parameters.
// Look for a ? to see if the url already includes query parameters
If (return_url_base.contains('?')) {
return_url_base += '&event=';
} Else {
return_url_base += '?event=';
}
urls.OnSigningComplete = return_url_base + 'signing_complete';
urls.OnViewingComplete = return_url_base + 'viewing_complete';
urls.OnCancel = return_url_base + 'cancel';
urls.OnDecline = return_url_base + 'decline';
urls.OnSessionTimeout = return_url_base + 'session_timeout';
urls.OnTTLExpired = return_url_base + 'ttl_expired';
urls.OnException = return_url_base + 'exception';
urls.OnAccessCodeFailed = return_url_base + 'failed_access_code';
urls.OnIdCheckFailed = return_url_base + 'failed_id_check';
urls.OnFaxPending = return_url_base + 'fax_pending';
// Step 3. Make the call
try {
signer_view_url = api_sender.RequestRecipientToken(
envelope_id, signer_user_id, signer_name, signer_email, assertion, urls);
System.debug('Received signer_view_url: = ' + signer_view_url);
} catch ( CalloutException e) {
System.debug('Exception - ' + e );
error_code = 'Problem: ' + e;
error_message = error_code;
}
}
Private void send_envelope() {
// Sends an envelope. The first signer is "captive," so he can sign embedded
// Check input
if (String.isBlank(signer_email) || String.isBlank(signer_name) || !signer_email.contains('#')) {
error_message = 'Please fill in the email and name fields';
error_code = 'INPUT_PROBLEM';
return;
}
// Check configuration
if (integration_key == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' ||
account_id == 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx') {
error_message = 'Please configure the Apex class DS_Recipe_Send_Env_Email_Controller with your integration key and account id.';
error_code = 'CONFIGURATION_PROBLEM';
return;
}
DocuSignTK.Recipient recipient = new DocuSignTK.Recipient();
recipient.Email = signer_email;
recipient.UserName = signer_name;
recipient.ID = 1;
recipient.Type_x = 'Signer';
recipient.RoutingOrder = 1;
recipient.RoleName = 'Signer';
// We want this signer to be "captive" so we can use embedded signing with him
recipient.CaptiveInfo = new DocuSignTK.RecipientCaptiveInfo();
recipient.CaptiveInfo.ClientUserID = signer_user_id; // Must uniquely identify the
DocuSignTK.ArrayOfRecipient1 recipients = new DocuSignTK.ArrayOfRecipient1();
recipients.Recipient = new DocuSignTK.Recipient[1];
recipients.Recipient[0] = recipient;
// Create the template reference from a server-side template ID
DocuSignTK.TemplateReference templateReference = new DocuSignTK.TemplateReference();
templateReference.Template = '37041580-9d59-4b41-a7c4-7c9bfa3b26c8';//'d0d80082-612b-4a04-b2a1-0672eb720491';
templateReference.TemplateLocation = 'Server';
//templateReference.Sequence = 1;
DocuSignTK.ArrayOfTemplateReferenceRoleAssignment Roles = new DocuSignTK.ArrayOfTemplateReferenceRoleAssignment();
Roles.RoleAssignment = new DocuSignTK.TemplateReferenceRoleAssignment[1];
DocuSignTK.TemplateReferenceRoleAssignment role = new DocuSignTK.TemplateReferenceRoleAssignment();
role.RoleName = 'Signer';
role.RecipientID = 1;
Roles.RoleAssignment[0] = role;
templateReference.RoleAssignments = Roles;
// Construct the envelope information
DocuSignTK.EnvelopeInformation envelopeInfo = new DocuSignTK.EnvelopeInformation();
envelopeInfo.AccountId = account_Id;
envelopeInfo.Subject = 'Subject';
envelopeInfo.EmailBlurb = 'Email content';
DocuSignTK.TemplateReferenceFieldDataDataValue fd2 = new
DocuSignTK.TemplateReferenceFieldDataDataValue();
fd2.TabLabel = 'name';
fd2.Value = 'recipient.UserName';
DocuSignTK.TemplateReferenceFieldDataDataValue fd3 = new
DocuSignTK.TemplateReferenceFieldDataDataValue();
fd3.TabLabel = 'company';
fd3.Value = 'company';
templateReference.FieldData = new DocuSignTK.TemplateReferenceFieldData();
templateReference.FieldData.DataValues = new
DocuSignTK.ArrayOfTemplateReferenceFieldDataDataValue();
templateReference.FieldData.DataValues.DataValue = new
DocuSignTK.TemplateReferenceFieldDataDataValue[2];
templateReference.FieldData.DataValues.DataValue[0] = fd2;
templateReference.FieldData.DataValues.DataValue[1] = fd3;
// Make the call
try {
//DocuSignTK.EnvelopeStatus result = api_sender.CreateAndSendEnvelope(envelope);
// Create draft with all the template information
DocuSignTK.ArrayOfTemplateReference TemplateReferenceArray = new DocuSignTK.ArrayOfTemplateReference();
TemplateReferenceArray.TemplateReference = new DocuSignTK.TemplateReference[1];
TemplateReferenceArray.TemplateReference[0] = templateReference;
DocuSignTK.EnvelopeStatus result = api_sender.CreateEnvelopeFromTemplates( TemplateReferenceArray, recipients, envelopeInfo, true);
envelope_id = result.EnvelopeID;
System.debug('Returned successfully, envelope_id = ' + envelope_id );
} catch ( CalloutException e) {
System.debug('Exception - ' + e );
error_code = 'Problem: ' + e;
error_message = error_code;
}
}
Private Boolean no_error() {
return (String.isEmpty(error_code));
}
}
DocuSign Website uses RESTAPI to send Payment details in an envelope. Payment related APIs are not available in SOAP calls, please try using REST API for payment related calls.
Related
I'm using RequestJWTUserToken (docusign.esign.dll file version 4.1.1.0) to generate access tokens for a web application for each user, however occasionally the web application is sending documents from the wrong User's account.
I have logged the steps of the application, and when the error occurs, 2 (or more) of the my users are authenticating their UserIDs through our Integrator key at about the exact same time.
Each user is re-authenticating each time it is time to send a document. The logs that I'm writing show that I am sending in the correct GUID in the parameter list to the RequestJWTUserToken method. Any ideas on what could be occurring?
The method snippet is:
private OAuth.OAuthToken UpdateToken(string strUserGuid)
{
try
{
string ServicePointManager_SecurityProtocol_TLS_12 = ConfigurationManager.AppSettings["ServicePointManager_SecurityProtocol_TLS_12"];
System.Collections.Specialized.NameValueCollection obj = ConfigurationManager.AppSettings;
if (ServicePointManager_SecurityProtocol_TLS_12 == null || ServicePointManager_SecurityProtocol_TLS_12.Equals("true", StringComparison.OrdinalIgnoreCase)) ServicePointManager.SecurityProtocol = Tls12;
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
var mtype = ServicePointManager.SecurityProtocol;
OAuth.OAuthToken authToken =
ApiClient.RequestJWTUserToken(IntegratorKey,
strUserGuid,
AuthServer,
PrivateKey,
1);
AccessToken = authToken.access_token;
//set Account Property
if (Account == null) Account = GetAccountInfo();
ApiClient = new ApiClient(Account.BaseUri + "/restapi");
ExpiresIn = DateTime.Now.Second + authToken.expires_in.Value;
return authToken;
}
catch (ApiException ex)
{
if (ex.Source.Contains("DocuSign.eSign") && strUserGuid != "")
{
if (ex.Message.Contains("consent_required")) //send email with consent to sign link
throw new Exception("DocuSign Consent Required for " + HttpContext.Current.Session["USER_FULLNAME"]);
else
switch (ex.ErrorCode)
{
case 400: throw new Exception("Bad Request: The requested UserID may exist in DocuSign, but there is an issue with the Docusign User Account.");
default: throw new Exception("General Error");
}
}
else throw;
}
catch
{
throw;
}
}
I am trying to programmatically create Users with Internal Accounts as part of a testing system. The following code can not create an InternalLogin because there is not password hash set at object creation time.
Can a person + internal account be created using metadata_* functions ?
data _null_;
length uri_Person uri_PW uri_IL $256;
call missing (of uri:);
rc = metadata_getnobj ("Person?#Name='testbot02'", 1, uri_Person); msg=sysmsg();
put 'NOTE: Get Person, ' rc= uri_Person= / msg;
if rc = -4 then do;
rc = metadata_newobj ('Person', uri_Person, 'testbot02'); msg=sysmsg();
put 'NOTE: New Person, ' rc= uri_Person= / msg;
end;
rc = metadata_setattr (uri_Person, 'DisplayName', 'Test Bot #2'); msg=sysmsg();
put 'NOTE: SetAttr, ' rc= / msg;
rc = metadata_newobj ('InternalLogin', uri_IL, 'autobot - IL', 'Foundation', uri_Person, 'InternalLoginInfo'); msg=sysmsg();
put 'NOTE: New InternalLogin, ' rc= / msg;
run;
Logs
NOTE: Get Person, rc=-4 uri_Person=
NOTE: New Person, rc=0 uri_Person=OMSOBJ:Person\A5OJU4RB.AP0000SX
NOTE: SetAttr, rc=0
NOTE: New InternalLogin, rc=-2
ERROR: AddMetadata of InternalLogin is missing required property PasswordHash.
NOTE: DATA statement used (Total process time):
real time 0.02 seconds
cpu time 0.01 seconds
The management console and metabrowse were used to find what objects might need to be created.
Metabrowse
I ended up using Java to create new users.
A ISecurity_1_1 instance from MakeISecurityConnection() on the metadata connection was used to SetInternalPassword
Java ended up being a lot more clear coding wise.
package sandbox.sas.metadata;
import com.sas.iom.SASIOMDefs.GenericError;
import com.sas.metadata.remote.*;
import com.sas.meta.SASOMI.*;
import java.rmi.RemoteException;
import java.util.List;
/**
*
* #author Richard
*/
public class Main {
public static final String TESTGROUPNAME = "Automated Test Users";
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
String metaserver="################";
String metaport="8561";
String omrUser="sasadm#saspw";
String omrPass="##########";
try
{
MdFactoryImpl metadata = new MdFactoryImpl(false);
metadata.makeOMRConnection(metaserver,metaport,omrUser,omrPass);
MdOMIUtil util = metadata.getOMIUtil();
ISecurity_1_1 security = metadata.getConnection().MakeISecurityConnection();
MdObjectStore workunit = metadata.createObjectStore();
String foundationID = util.getFoundationReposID();
String foundationShortID = foundationID.substring(foundationID.indexOf(".") + 1);
// Create group for test bot accounts
List identityGroups = util.getMetadataObjects(foundationID, MetadataObjects.IDENTITYGROUP, MdOMIUtil.OMI_XMLSELECT,
String.format("<XMLSelect search=\"IdentityGroup[#Name='%s']\"/>", TESTGROUPNAME));
IdentityGroup identityGroup;
if (identityGroups.isEmpty()) {
identityGroup = (IdentityGroup) metadata.createComplexMetadataObject (workunit, TESTGROUPNAME, MetadataObjects.IDENTITYGROUP, foundationShortID);
identityGroup.setDisplayName(TESTGROUPNAME);
identityGroup.setDesc("Group for Automated Test Users performing concurrent Stored Process execution");
identityGroup.updateMetadataAll();
}
identityGroups = util.getMetadataObjectsSubset(workunit, foundationID, MetadataObjects.IDENTITYGROUP, MdOMIUtil.OMI_XMLSELECT,
String.format("<XMLSelect search=\"IdentityGroup[#Name='%s']\"/>", TESTGROUPNAME));
identityGroup = (IdentityGroup) identityGroups.get(0);
// Create (or Update) test bot accounts
for (int index = 1; index <= 25; index++)
{
String token = String.format("%02d", index);
String personName = String.format("testbot%s", token);
String password = String.format("testbot%s%s", token, token); * simple dynamically generated password for user (for testing scripts only);
String criteria = String.format("Person[#Name='%s']", personName);
String xmlSelect = String.format("<XMLSelect search=\"%s\"/>", criteria);
List persons = util.getMetadataObjectsSubset(workunit, foundationID, MetadataObjects.PERSON, MdOMIUtil.OMI_XMLSELECT | MdOMIUtil.OMI_GET_METADATA | MdOMIUtil.OMI_ALL_SIMPLE, xmlSelect);
Person person;
if (persons.size() == 1)
{
person = (Person) persons.get(0);
System.out.println(String.format("Have %s %s", person.getName(), person.getDisplayName()));
}
else
{
person = (Person) metadata.createComplexMetadataObject (workunit, personName, MetadataObjects.PERSON, foundationShortID);
person.setDisplayName(String.format("Test Bot #%s", token));
person.setDesc("Internal account for testing purposes");
System.out.println(String.format("Make %s, %s (%s)", person.getName(), person.getDisplayName(), person.getDesc()));
person.updateMetadataAll();
}
security.SetInternalPassword(personName, password);
AssociationList personGroups = person.getIdentityGroups();
personGroups.add(identityGroup);
person.setIdentityGroups(personGroups);
person.updateMetadataAll();
}
workunit.dispose();
metadata.closeOMRConnection();
metadata.dispose();
}
catch (GenericError | MdException | RemoteException e)
{
System.out.println(e.getLocalizedMessage());
System.exit(1);
}
}
}
I need to send a temporary password via email to an user when i register a new Teacher.
i use Membership.GeneratePassword to generate random password.
here is my TeacherController
[HttpPost]
public async Task<ActionResult> Create(TeacherViewModel viewModel)
{
if (!ModelState.IsValid)
{
var model = new TeacherViewModel()
{
Courses = _context.Courses.ToList(),
SituationActuelles = _context.SituationActuelles.ToList()
};
return View("Create", model);
}
var teacher = new Teacher
{
PhoneNumber = viewModel.PhoneNumber,
Password = viewModel.Password
};
_context.Teachers.Add(teacher);
_context.SaveChanges();
var body = "<p>Merci de votre interet a NewEra Tutoring Corp.</p> <br/>" +
"Vos credentials pour acceder a votre platform est le suivant: <br/>" +
"Email: Votre email<br/>" +
"Votre mot de passe temporaire: " + viewModel.Password;
var message = new MailMessage();
message.To.Add(new MailAddress(viewModel.Email)); // replace with valid value
message.From = new MailAddress("recrutement#newera-tutoring.com"); // replace with valid value
message.Subject = "Your email subject";
message.Body = string.Format(body, "NewEra Tutoring", "recrutement#newera-tutoring.com", "Votre identifiant pour NewEra Tutoring");
message.IsBodyHtml = true;
using (var smtp = new SmtpClient())
{
var credential = new NetworkCredential
{
UserName = "recrutement#newera-tutoring.com", // replace with valid value
Password = "neweratutoring" // replace with valid value
};
smtp.Credentials = credential;
smtp.Host = "gator4123.hostgator.com";
smtp.Port = 587;
smtp.EnableSsl = true;
await smtp.SendMailAsync(message);
}
return RedirectToAction("Index", "Home");
}
But the password i receive in the email it's different from the one that it's saved in the database.
here is my model
TeacherViewModel{
public string Password => Membership.GeneratePassword(12, 1);
}
Where i am doing wrong?
You've used an expression bodied member in the view model for the password property which essentially creates a get wrapper around the call to membership password.
Each time you access the property it generates a new password as it runs the function again.
I don't see why you'd want to have it in the view model at all unless your intention is to offer a random password that they user could replace with their own. If that was the aim use a standard property get/set and create an initial password value in the view model constructor instead. Otherwise, take it out o of the view model & only create the password in the post action if every thing else is valid.
I'm attempting to process creit cards through PayPal and keep getting this weird error:
{"name":"VALIDATION_ERROR","details":[{"field":"transactions[0].amount","issue":"Transaction
amount details (subtotal, tax, shipping) must add up to specified
amount total"}],"message":"Invalid request - see
details","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#VALIDATION_ERROR","debug_id":"6e2cef39d556a"}
Here's the method I'm using:
public ActionResult PaymentWithCreditCard(PayWithCCViewModel model)
{
var cart = ShoppingCart.GetCart(this.HttpContext);
var cartItems = cart.GetCartItems();
List<Item> orderItems = new List<Item>();
foreach (var cartItem in cartItems)
{
var item = new Item();
item.name = cartItem.Product.ProductName;
item.currency = "USD";
item.price = cartItem.ProductPrice.ToString();
item.quantity = cartItem.ProductQuantity.ToString();
orderItems.Add(item);
}
ItemList itemList = new ItemList();
itemList.items = orderItems;
//Address for the payment
Address billingAddress = new Address();
billingAddress.city = model.BillingCity;
billingAddress.country_code = "US";
billingAddress.line1 = model.BillingAddressLine1;
billingAddress.line2 = model.BillingAddressLine2;
billingAddress.postal_code = model.BillingPostalCode;
billingAddress.state = model.BillingState;
//Now Create an object of credit card and add above details to it
CreditCard card = new CreditCard();
card.billing_address = billingAddress;
card.cvv2 = model.CVV2;
card.expire_month = model.ExpirationMonth;
card.expire_year = model.ExpirationYear;
card.first_name = model.FirstName;
card.last_name = model.LastName;
card.number = model.Number;
card.type = model.CardType.ToString();
var subTotal = cart.GetTotal();
var tax = Convert.ToDouble(subTotal) * Convert.ToDouble(.076);
var total = Convert.ToDouble(subTotal) + tax;
// Specify details of your payment amount.
Details details = new Details();
details.shipping = "3";
details.subtotal = subTotal.ToString();
details.tax = tax.ToString();
// Specify your total payment amount and assign the details object
Amount amount = new Amount();
amount.currency = "USD";
// Total = shipping tax + subtotal.
amount.total = total.ToString();
amount.details = details;
// Now make a trasaction object and assign the Amount object
Transaction transaction = new Transaction();
transaction.amount = amount;
transaction.description = "Payment to AccessorizeForLess.net";
transaction.item_list = itemList;
transaction.invoice_number = cart.GetCartId(this.HttpContext);
// Now, we have to make a list of trasaction and add the trasactions object
// to this list. You can create one or more object as per your requirements
List<Transaction> transactions = new List<Transaction>();
transactions.Add(transaction);
// Now we need to specify the FundingInstrument of the Payer
// for credit card payments, set the CreditCard which we made above
FundingInstrument fundInstrument = new FundingInstrument();
fundInstrument.credit_card = card;
// The Payment creation API requires a list of FundingIntrument
List<FundingInstrument> fundingInstrumentList = new List<FundingInstrument>();
fundingInstrumentList.Add(fundInstrument);
// Now create Payer object and assign the fundinginstrument list to the object
Payer payr = new Payer();
payr.funding_instruments = fundingInstrumentList;
payr.payment_method = "credit_card";
// finally create the payment object and assign the payer object & transaction list to it
Payment pymnt = new Payment();
pymnt.intent = "sale";
pymnt.payer = payr;
pymnt.transactions = transactions;
try
{
//getting context from the paypal, basically we are sending the clientID and clientSecret key in this function
//to the get the context from the paypal API to make the payment for which we have created the object above.
// Basically, apiContext has a accesstoken which is sent by the paypal to authenticate the payment to facilitator account. An access token could be an alphanumeric string
APIContext context = PayPalModel.GetAPIContext();
// Create is a Payment class function which actually sends the payment details to the paypal API for the payment. The function is passed with the ApiContext which we received above.
Payment payment = pymnt.Create(context);
//if the createdPayment.State is "approved" it means the payment was successfull else not
if (payment.state.ToLower() != "approved")
{
return View("FailureView");
}
}
catch (PayPalException ex)
{
Logger.Log("Error: " + ex.Message);
return View("FailureView");
}
return View("SuccessView");
}
I've stepped through the code and the total, tax and shipping seem to be correct, anyone have issues when dealing with PayPal before that could led me t a solution?
I forgot to add shipping to the total, now I get an approval
We are trying to integrate docusign (Embedded signing / Embedded docusign console yet to decide which one) with an existing MVC 5 web application. I was looking for a starting point and came across your question. I have looked at the API walkthrough(7,8,9) , but I want to know how to start off. For example we will need to direct the user to an application form for them to fill out and sign after they register on the site. Post signing I would like to redirect them back to the website.
Any pointers or examples would be much appreciated.
Thanks much, Sunny
Below is my code - which was working till last firday ( but from yesterday I getting this error -
"406 - Client browser does not accept the MIME type of the requested page.
The page you are looking for cannot be opened by your browser because it has
a file name extension that your browser does not accept."
protected const string IntegratorKey = "XXX-XXX";
protected const string Environment = "http://demo.docusign.net";
static void Main(string[] args)
{
// Example #1...
Console.WriteLine("Testing Walkthrough #7...");
// configure application's integrator key, webservice url, and rest api version
RestSettings.Instance.IntegratorKey = IntegratorKey;
RestSettings.Instance.DocuSignAddress = Environment;
RestSettings.Instance.WebServiceUrl = Environment + "/restapi/v2";
docusign test = new docusign();
test.EmbeddedSigning();
Console.ReadLine(); // pause to show console output
}
private void EmbeddedSigning()
{
//*****************************************************************
// ENTER VALUES FOR FOLLOWING VARIABLES!
//*****************************************************************
string AccountEmail = "s#something.com";
string AccountPassword = "*****";
string EnvelopeId = "xxxxxxx";
string RecipientEmail = "s#someone.com";
string RecipientName = "someone";
//*****************************************************************
// user credentials
Account account = new Account();
account.Email = AccountEmail;
account.Password = AccountPassword;
// make the login call (retrieves your baseUrl and accountId)
bool result = account.Login();
if (!result)
{
Console.WriteLine("Login API call failed for user {0}.\nError Code: {1}\nMessage: {2}", account.Email, account.RestError.errorCode, account.RestError.message);
return;
}
// create envelope object and assign login info
Envelope envelope = new Envelope();
envelope.Login = account;
// assign the envelope id that was passed in
envelope.EnvelopeId = EnvelopeId;
//add one signer (single recipient embedded signing currently supported in DocuSign .NET Client)
envelope.Recipients = new Recipients()
{
signers = new Signer[]
{
new Signer()
{
email = RecipientEmail,
name = RecipientName,
recipientId = "1",
clientUserId = "1"
}
}
};
try
{
result = envelope.GetRecipientView("http://example.com/");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine(envelope.SenderViewUrl);
Console.ReadLine();
if (!result)
{
if (envelope.RestError != null)
{
Console.WriteLine("Error code: {0}\nMessage: {1}", envelope.RestError.errorCode, envelope.RestError.message);
Console.ReadLine();
return;
}
else
{
Console.WriteLine("Error encountered retrieving signing token, please review your envelope and recipient data.");
return;
}
}
else
{
// open the recipient view (SenderViewUrl field is re-used for the recipient URL)
Process.Start(envelope.SenderViewUrl);
}
}
Embedded Signing
Embedded Signing does exactly what you want with the returnUrl parameter. This also allows the signer to sign without signing up for a DocuSign account, to streamline the process a bit more.
Check out DocuSign's
Embedded Signing REST API Walkthrough