我有一个在 docusign UI 中创建的模板。当我最终得到收件人查看 URL 时,我将其放入 URL 中。除非我使用我注册 DocUSign 时使用的登录详细信息,否则文本和签名选项卡在合同中不可见。
在此示例中,假设我的注册详细信息是:
在下面的第一个代码示例中,收件人视图不允许我签署合同。
在下面的第二个代码示例中,我被允许签署合同。就像 DocUSign 似乎知道是我在查看文档,尽管我处于隐身模式。
下面两个代码示例之间的唯一区别是 requestData,其中后者使用我注册时使用的登录详细信息具有附加角色。
值得注意的是:
电子邮件:“[email protected]”, 名称:“fullstackryan”,
没有 DocUSign 帐户,但您认为这并不重要吗?因为我们不想强迫我们的客户先注册?
import { NextResponse } from "next/server";
import axios, { AxiosResponse } from "axios";
import { convertPenniesToPounds } from "@/lib/convertPenniesToPounds";
type TextTab = {
anchorString: string;
anchorUnits: string;
anchorXOffset: string;
anchorYOffset: string;
tabLabel: string;
width?: string;
value?: string;
};
type TemplateRole = {
email: string;
name: string;
roleName: string;
tabs?: {
signHereTabs?: TextTab[];
textTabs?: TextTab[];
};
};
type RequestData = {
templateId: string;
templateRoles: TemplateRole[];
status: string;
};
const createEnvelope = async (
templateId: string,
signerEmail: string,
signerName: string,
renewalPrice: string
): Promise<any> => {
const requestData: RequestData = {
templateId,
templateRoles: [
{
email: "[email protected]",
name: "fullstackryan",
roleName: "placeholder",
tabs: {
signHereTabs: [
{
anchorString: "/XSIGNHEREX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "signHere",
},
],
textTabs: [
{
anchorString: "/LegalRenewalPrice/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "renewalPrice",
width: "100",
value: renewalPrice,
},
],
},
},
],
status: "sent",
};
const config = {
headers: {
Authorization: `Bearer ${process.env.DOCUSIGN_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
};
try {
const response = await axios.post(
`${process.env.DOCUSIGN_BASE_URI}accounts/${process.env.DOCUSIGN_API_ACCOUNT_ID}/envelopes`,
requestData,
config
);
return response.data;
} catch (error) {
console.error("Error sending request:", error);
throw error;
}
};
const createRecipientView = async (
envelopeId: string,
accountId: string,
returnUrl: string,
userName: string,
userEmail: string
): Promise<AxiosResponse> => {
const requestData = {
returnUrl,
authenticationMethod: "None",
email: userEmail,
userName,
};
const config = {
headers: {
Authorization: `Bearer ${process.env.DOCUSIGN_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
};
try {
const response = await axios.post(
`${process.env.DOCUSIGN_BASE_URI}accounts/${accountId}/envelopes/${envelopeId}/views/recipient`,
requestData,
config
);
return response.data.url;
} catch (error) {
console.error("Error creating recipient view:", error);
throw error;
}
};
export async function POST(request: Request) {
const { templateId, name, email, renewalPrice } = await request.json();
try {
const data = await createEnvelope(
templateId,
"[email protected]",
"fullstackryan",
convertPenniesToPounds(renewalPrice)
);
const viewUrl = await createRecipientView(
data.envelopeId,
`${process.env.DOCUSIGN_API_ACCOUNT_ID}`,
"http://localhost:3000/",
"fullstackryan", // what's username for and where does it come
"[email protected]"
);
return NextResponse.json({
recipientView: viewUrl,
envelopeId: data.envelopeId,
});
} catch (error) {
console.error("Failed to send the request:", error);
return NextResponse.json({ error: "Failed to send the request" });
}
}
下面的第二个代码示例:
import { NextResponse } from "next/server";
import axios, { AxiosResponse } from "axios";
import { convertPenniesToPounds } from "@/lib/convertPenniesToPounds";
type TextTab = {
anchorString: string;
anchorUnits: string;
anchorXOffset: string;
anchorYOffset: string;
tabLabel: string;
width?: string;
value?: string;
};
type TemplateRole = {
email: string;
name: string;
roleName: string;
tabs?: {
signHereTabs?: TextTab[];
textTabs?: TextTab[];
};
};
type RequestData = {
templateId: string;
templateRoles: TemplateRole[];
status: string;
};
const createEnvelope = async (
templateId: string,
signerEmail: string,
signerName: string,
renewalPrice: string
): Promise<any> => {
const requestData: RequestData = {
templateId,
templateRoles: [
{
email: "[email protected]",
name: "fullstackryan",
roleName: "placeholder",
tabs: {
signHereTabs: [
{
anchorString: "/XSIGNHEREX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "signHere",
},
],
textTabs: [
{
anchorString: "/XLEGALRENEWALPRICEX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "renewalPrice",
width: "100",
value: renewalPrice,
},
],
},
},
{
email: "[email protected]",
name: "Ryan lastname",
roleName: "placeholder",
tabs: {
signHereTabs: [
{
anchorString: "/XSIGNHEREX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "signHere",
},
],
textTabs: [
{
anchorString: "/XLEGALRENEWALPRICEX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "renewalPrice",
width: "100",
value: renewalPrice,
},
],
},
},
],
status: "sent",
};
const config = {
headers: {
Authorization: `Bearer ${process.env.DOCUSIGN_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
};
try {
const response = await axios.post(
`${process.env.DOCUSIGN_BASE_URI}accounts/${process.env.DOCUSIGN_API_ACCOUNT_ID}/envelopes`,
requestData,
config
);
return response.data;
} catch (error) {
console.error("Error sending request:", error);
throw error;
}
};
const createRecipientView = async (
envelopeId: string,
accountId: string,
returnUrl: string,
userName: string,
userEmail: string
): Promise<AxiosResponse> => {
const requestData = {
returnUrl,
authenticationMethod: "None",
email: userEmail,
userName,
};
const config = {
headers: {
Authorization: `Bearer ${process.env.DOCUSIGN_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
};
try {
const response = await axios.post(
`${process.env.DOCUSIGN_BASE_URI}accounts/${accountId}/envelopes/${envelopeId}/views/recipient`,
requestData,
config
);
return response.data.url;
} catch (error) {
console.error("Error creating recipient view:", error);
throw error;
}
};
export async function POST(request: Request) {
const { templateId, name, email, renewalPrice } = await request.json();
try {
const data = await createEnvelope(
templateId,
"[email protected]",
"fullstackryan",
convertPenniesToPounds(renewalPrice)
);
const viewUrl = await createRecipientView(
data.envelopeId,
`${process.env.DOCUSIGN_API_ACCOUNT_ID}`,
"http://localhost:3000/",
"fullstackryan", // what's username for and where does it come
"[email protected]"
);
return NextResponse.json({
recipientView: viewUrl,
envelopeId: data.envelopeId,
});
} catch (error) {
console.error("Failed to send the request:", error);
return NextResponse.json({ error: "Failed to send the request" });
}
}
发送信封时我没有传递“clientUserId”。我现在已将其添加到请求数据中。此外,在创建收件人视图时,您必须传递相同的 clientUserId。请参阅底部代码摘录。 clientUserId 由您选择,只要它与您传递给信封和收件人视图的创建的相同,那么您应该没问题。例如,您可以使用 clientUserID:“1234”
const requestData: TemplateRequest = {
templateId,
templateRoles: [
{
email: firmEmail,
name: firmContactName,
roleName: "signer",
clientUserId,
tabs: {
signHereTabs: [
{
anchorString: "/XSIGNHEREX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "signHere",
},
],
textTabs: [
{
anchorString: "/XLEGALRENEWALPRICEX/",
anchorUnits: "pixels",
anchorXOffset: "20",
anchorYOffset: "10",
tabLabel: "renewalPrice",
width: "100",
value: renewalPrice,
},
],
},
},
],
status: "sent",
};
const requestData = {
returnUrl,
authenticationMethod: "None",
email: userEmail,
userName,
clientUserId,
};