通过 Alpha 案例库检索计算机软件开发合同纠纷可以发现,软件开发合同就有由 2012 年的仅有 13 个案例到如今上千个案例,上涨飞速。
并且由于软件工程的规模越大、技术难度越大、功能越新颖,工程逾期概率越高,失败概率也越高的特点,导致软件工程的违约风险极高。今日文章,一起和作者学习律师如何设计软件开发合同,规避风险,让客户更满意。
软件开发合同较特殊,除法律要素外,还涉及计算机行业知识,这给法律实务带来障碍。所幸,软件工程具有一些共性,这意味着能总结出风险要素,作为设计合同的原则或重点,从而提高软件开发合同的质量。
鉴于大型软件工程的个性化特征很多,而且大型软件公司已具备一定的法律成熟度。为提高本文实用性和普适性,本文主要针对中小型软件工程。
在软件开发合同中,合同主体一般有两方,本文称之为“开发者”和“客户”,开发者一般是软件企业或个人开发者,受托开发软件并收取开发费用,客户是接收软件的企业或个人,支付开发费用。
例如,一份软件开发合同约定开发“葡萄酒网上商城”,“开发者”可能是一家软件公司,“客户”可能是接收并运营该 “葡萄酒网上商城”的商业公司。
首先要了解,在软件工程实践中,能在预定开发周期内准时完工的软件工程较少,要么是微小规模项目,要么是复用项目(已开发过同类项目,手中有可重复使用的源代码),要么是增量开发(为已有软件增加新功能)。
一般来说,软件工程的规模越大、技术难度越大、功能越新颖,工程逾期概率越高,失败概率也越高。由于这个固有特点,软件工程的违约风险极高,所以设计和审查软件开发合同的首要原则是:“重视任何可能触发违约的合同条款;重视任何有关期限、时限的合同条款”。
一、设计软件开发合同,
律师、法务应在何时开始工作?
在一般中小型商务合同中,律师、法务通常从委托人那里间接了解商务逻辑,然后设计或审核合同,尽管并未参加商务谈判,但能够大致准确的理解商务内容并设计合同。
软件工程不同,其高风险多隐藏在初始阶段,应当提早介入。理想介入时点是需求分析阶段的开始。一项软件工程可以大致分五个阶段:需求分析、结构设计、代码实现、软件测试、部署运行。
需求分析是软件工程的第一个阶段,此时开发者与客户反通交流,明确理解“软件要具备什么功能,达到什么性能指标”。此阶段是后续工作的基础,决定着后期的技术策略、研发周期、研发费用、研发进度等等。
一旦需求分析出现偏差,这些偏差会在后期放大,会使结构设计、代码实现、软件测试等等后续阶段产生大量无效工作。在软件工程实践中,大量项目的逾期、失败是由需求分析缺陷所致,这也就必然导致巨大的违约风险。
律师、法务在此阶段介入,能直接面对客户,能最大化减少信息传递损耗,能和需求分析师以及客户进行多方位沟通,最大化消除理解偏差,经过这样的程序,再将需求内容规范化成法律文本,软件开发合同的质量会大大提高。
二、软件开发合同的结构安排
建议将合同主要分为两部分:主合同、需求说明书。
(一)主合同条款分为两类条款:通用条款和特殊条款。通用条款指价格条款、支付条款、违约责任、保密条款、竞业限制等通用性条款,本文不赘述此类条款。本
文关注特殊条款,即软件开发合同的独有条款、或者应当特别重视的条款。
(二)需求说明书是最重要的附件。在软件工程中,也称之为“需求规格说明书”、“需求分析说明书”,在软件工程技术层面,它是“需求分析阶段”的工作成果,是后续工作的凭证和起点,是软件工程中最重要的文档。
在法律层面,若发生争议进入诉讼或仲裁,需求说明书是据以判定合同是否可解除(根本违约)、是否形成违约责任的最重要依据。
在软件工程实践中,需求说明书通常由技术人员撰写,关注工程技术层面,忽略了法律层面考虑,致使一些软件工程争议陷入被动。
三、主合同的特殊条款
主合同中的特殊条款主要包括:支持环境条款、功能变更条款、交付条款、后续服务条款。
(一)支持环境条款。是指运行目标软件所需的硬件环境和软件环境。硬件环境,主要包括主机规格、处理器规格、内存要求、存储器容量、网络环境等,软件环境,主要包括操作系统,数据库,应用服务器,第三方组件等。支持环境一般由客户自行配置安装,虽然在形式上属于客户义务,却能给开发者带来法律风险。
硬件条款相对简单,虽然计算机硬件品牌众多,但是这些计算机的体系结构都是规范的,通常遵循统一的行业标准。
例如一台 IBM 的 PC 机和 Dell 的 PC 机并没有区别。硬件条款应约定相关硬件的具体规格,例如处理器版本、内存大小等。
软件条款相对复杂,是合同设计的重点。几乎任何软件都需要其他软件的支持,可以说,除非这项软件工程的任务是开发操作系统,否则该软件一定需要其他软件支持,至少需要操作系统。
例如,我们使用 word,至少需要计算机装有 Windows 系统,我们使用微信,至少需要手机装有 Android 操作系统或者 iOS 操作系统。
1.操作系统。要注明操作系统版本号,例如,“Windows 10”、“Android V11.0”。不应使用“Windows系统”、“Android 系统”、“主流操作系统”、“通用的操作系统”这种笼统表述。
如果客户要求目标软件能够适应未来操作系统升级,应当使用“兼容”这个技术名词。例如,使用“Windows10 及兼容 windows 10 的操作系统”这种表述方式,不应使用“Windows10 及 windows 10以上版本的操作系统”之类的表述。
新版本操作系统未必能兼容旧版本操作系统,例如很多 Windows7 程序在 windows10 已经不能使用。如果合同未做兼容性约定,将来客户升级操作系统,一旦新版本操作系统不兼容旧版本,开发者就可能必须对软件做出变更修改,会意外增加工作量和开发成本。
如果客户要求软件支持多个平台,应当明确列示操作系统名称,不应使用概括性语句。多数软件一般不能跨平台运行,例如,windows 的软件通常不能运行在 Linux 或 UNIX 操作系统。虽然常见的手机应用(例如微信、支付宝),能在 Android 手机使用,也能 Apple 手机使用,事实上这是两套不同的软件,它们仅是功能相同,要编写两份不同的源代码,需要近两倍工作量。合同条款一旦约定不明确,可能触发意外违约。
例如,假设一份合同约定“……支持所有主流手机系统”,假设在软件工程进行过程中,华为公司突然正式推出了“鸿蒙”操作系统,替换了某个机型的原有 Android 系统,而该手机又占据很大市场份额,那么开发者是否要再多耗费一倍的工作量和开发周期,为客户再开发一套支持鸿蒙系统的软件呢?这很容易导致争议。
2.数据库、应用服务器条款类似于操作系统条款,不赘述。
3.第三方组件。在软件工程实践中,开发者可能会使用来自外部的“零部件”,这些“零部件”具有特定功能,能够直接嵌入目标软件,使开发者不再需要为这些特定功能编写代码,从而能提高开发效率,降低开发成本。
有时,第三方组件会和客户某些软件产生未知冲突,导致客户的某些软件无法正常工作,这可能产生争议。因此,设计软件开发合同时,要询问开发者的技术人员,弄清楚是否会使用第三方组件,如果使用第三方组件,建议在合同中约定,将该类组件设置为支持环境的一部分,由客户自行配置安装这些组件。
有时,某些组件还存在特别的授权限制,例如,某些组件具有开发者版本和商用版本。开发者研究开发免费,但不容许开发者转授权,这也需要由客户自行配置安装,而不能由开发者直接集成到软件内,以避免法律风险。
(二)功能变更条款。是指在软件工程进行中,客户提出增加、减少、修改软件功能。在软件工程实践中,由于各种主客观原因,功能变更是无法避免的,重要的是如何规范这种变更。
软件减少功能一般不会增加工作量及工程风险,增加新功能必然增加工作量及工程风险,而修改功能有很大不确定性,是合同设计的重点。
修改功能是对软件某个或某些子功能做出变更。如果这个功能模块已经开发完成,该功能已经占用了工作量,占用了开发周期,也产生了开发成本。此时,修改该功能实质是废弃该功能增加新功能,这种变更必然会增加工作量及工程风险。
如果这个功能模块尚未开发,但与其他已完成的功能有关联,修改这个未开发的功能,会间接影响关联功能,导致需要修改关联功能,这仍然会增加工作量。仅当这个功能模块尚未开发,而且功能代码独立于其他功能模块,对其修改才无影响。
问题在于,当争议发生时,裁判者可能难以判断,可能会将证明“修改该功能导致工程量增加、周期延误”的证明责任置于开发者,从而产生法律风险。
本条款注意几点。1.明确功能变更的方式。例如“……经书面约定且经双方签字盖章”。2.调整软件开发周期。
在软件工程实践中,当客户提出功能变更,开发者一般首先要研究该功能对项目产生的影响,然后研究决策是否接受该变更,这都需要时间,所以要调增开发周期,否则加大违约风险。例如“自收到……功能变更请求或询问时,暂停计算开发周期,待……日后继续开始计算,或……书面表示是否接受变更后再恢复计算”。
开发者与客户若最终接受变更,应针对该变更另行签订补充合同。在补充合同中,除了约定开发费用、约定新功能之外,还应当调增开发周期,例如“增加……工作日的开发周期”。
(三)交付条款。是指将目标软件及相关附件送达给客户,或将该软件及附件的控制权转移给客户。软件类型不同,交付内容及方式也不同,随着软件行业发展,交付内容及方式可能随之变化。条款重点是以下几点。
1.开发周期。应根据软件工程师的技术判断,在合同中明确开发周期,应当使用相对期限。例如“自合同签订后……工作日内交付”,“自合同签订后……个月内交付”这类表述,不应使用“在…年…月…日前交付”此类表述。
2.交付内容。是指软件开发完成后形成的成果,有哪些成果要移送给客户,这些成果通常是一系列文件。合同要说明包括哪些文件,以及不包括哪些文件。
因为,一旦约定不明发生争议,裁判者可能会参照行业标准作为裁判依据,但我国多数行业规范及出版物中定义的“软件产品”内涵太广,有些文件是中小型软件工程根本无法产生的“成果”,这可能会对开发者不利,所以要明确约定。
例如“……交付内容包括:执行程序,文件扩展名为*.exe;数据库初始化脚本,扩展名为*.sql;不包含执行程序的源代码;不包含软件使用说明书及其他文件。”
3.交付方式,主要 3 种。开发者将存有交付内容的光盘或其他存储介质送达客户;开发者通过网络将文件传输给客户,无介质。例如“将……发送至邮箱……@qq.com”;开发者将交付内容提交至第三方平台,然后将控制权交付给客户,例如“将……手机应用软件上传至Apple 官方应用商城 AppStore,并将管理员用户名、密码发送至邮箱……@qq.com”。
4.客户的协助义务。在某些交付方式中,需要客户履行某些在先义务。例如,将开发完成的手机应用上传至Apple 官方应用商城 AppStore,开发者需要为客户创建一个 AppStore 账号,这时可能需要客户提供其营业执照等资料,这种义务应当在合同中明确约定。
在某些情况下,由于某种原因,开发者无法为客户注册平台账号。例如, AppStore 基于某些原因禁止了该客户,开发者将无法为客户注册,从而无法将手机程序上传至Apple 应用商店,进而无法完成交付。如果发生争议,裁判者可能会认为“客户是不懂技术的但开发者足够专业,因此开发者有前期审查义务和提示义务”,从而将举证责任转置给开发者,所以要明确约定。
例如“不承担……由于客户条件不具足而无法创建账号,导致无法交付而产生的损失”,或者约定“若由于客户条件不具足而无法创建账号,导致无法上传至 Apple官方应用商城 AppStore,可将交付成果邮件发送到客户邮箱……@qq.com”。
(四)验收条款。在软件工程实践中,开发者将软件成果交付给客户后,通常需要给客户一个检查验收期。在此期间,客户使用业务数据测试软件的功能,判断是否满足约定。客户测试无异议后,向开发者表示通过验收,软件工程将进入后期维护阶段。
一个合格的软件工程,在交付之前会经过开发者内部测试,交付后的软件通常不具有重大的错误(一般称为 bug),然而最优秀的软件工程也无法完全避免错误。因此,在设计本条款时,要秉持一个基本假设:“假设交付的软件一定存在着错误”。条款主要是以下几点。
1.验收期限。验收期限应是相对期限。例如“自软件成果交付后……工作日内验收完成”,“自软件成果交付后……工作日内未反馈验收结果,……视为验收合格”,不使用“在…年…月…日前验收完成”这类表述。
验收期限应是动态期限,合同应约定,当发现软件存在错误时,应暂停计算验收期限,待开发者修正错误后继续计算,这样可以降低和缓冲法律风险。如果不为开发者设置错误修正机会,软件一旦出现错误导致争议,裁判者就有可能直接认定软件不合格,合同可能被判解除。
如果在错误修正期间不暂停验收期,则意味着开发者的过错却导致客户验收期减少,客户很可能无法接受。设置动态期限有妥协价值,能够防止争议的极端化,避免争议焦点走向“软件合格”或“软件不合格”。比如“自……确认并反馈软件错误之日起,……验收期限暂停计算,至该错误修正后继续开始计算”。
2.错误修正期。在软件验收期内,发现错误后,开发者要修正这些错误,这必然延迟该软件的正式部署运行,客户不会无限期容忍。
实践中需要向客户妥协,本文的建议是,根据“错误修改总耗时”设置违约条款,就是将开发者在验收期内修正所有错误耗费的时间相加,如果时间总和超过某个界限则向客户承担一定的违约责任。
例如“自软件成果交付后……至验收完成前,……修改各错误总耗时超过……工作日的,每超过7个工作日向客户支付……元”。
3.软件错误信息反馈。软件验收测试时,客户可能发现了软件异常,但真实原因可能很多,可能是软件确实存在错误,也可能是客户操作错误导致,还可能是软件的支持环境存在问题(例如硬件存在问题,或者操作系统存在问题)。
设计错误反馈条款时,信息要详细充分,否则开发者难以定位错误。条款至少应包含以下 3 点信息:“性发生错误前实施的软件操作;发生错误前输入的数据;发生错误时的图像截屏。”
4.其他考虑。应避免设置“验收不合格”条件,不合格基本意味着根本违约,合同被裁判解除的风险很大,一旦解除合同,开发者不但没有收益,前期开发成本也可能会全部损失。
尤其不要以验收期发现的软件错误数量作为“验收不合格”条件,因为有些错误可能无关紧要,而有些“客户发现的软件异常”未必真的属于软件错误,更重要的是,对软件错误定性时很可能涉及到技术细节问题。若发生争议,这种条款可能会使诉讼陷入技术性细节,多数律师和法务不熟悉软件开发技术,这会增加法律风险。
(五)后续服务条款。是指软件验收合格后,客户将软件部署在生产环境正式运行使用,开发者开始向客户提供一段时期的技术支持,主要工作是修正新发现的错误,并提供技术咨询。
在软件工程实践中,验收合格后发现的新软件错误,不同于验收期发现的错误,开发者一般不承担某种违约责任,而是属于服务义务的一部分,但开发者仍要修正。
基于折中考虑,本条款可以结合软件项目尾款进行设计,例如“自软件成果交付验收完成后,后续服务期内……修改各错误总耗时超过……工作日的,每超过7日……扣除项目尾款……元”。
四、需求说明书的设计要点
前文提到过,不论从工程技术角度,还是法律风险角度,需求说明书都是最重要的文档。在软件工程实践中,需求说明书的内容、格式、及风格纷繁多样,没有统一标准。
虽然我国发布过软件行业标准的编制指南,但在实践中不普及,也不适合于中小型软件工程,更重要的是,该指南是从技术层面阐述,忽略了法律层面的考虑,它涉及很多专业术语,不利于裁判者、律师、法务理解,这必然会增加法律风险和成本。
概况的说,软件工程中的需求说明书是个技术文档,不适合作为合同文本中的需求说明书。作为合同组成部分的需求说明书,应遵循不同的原则,使用不同的表达方式。设计或修改需求说明书时,考虑以下几点。
(一)使用文字描述,避免引用模型图。在软件工程理论与实践中,描述软件需求时经常使用某种模型图,传统的结构化方法有数据流模型,面向对象方法有UML(统一建模语言),从工程技术层面,模型图能更好服务于软件工程后期工作,比如结构设计和代码编写,但在法律层面,这些技术模型难以被裁判者、律师、法务理解,会增加法律风险和成本,因而需求说明书作为合同文本时,应使用文字而非模型图。
(二)用格式化句式精确表达需求,一条语句应仅表达一个需求。在软件工程的需求分析方法中,结构化方法将软件视为数据变换,即“待处理的数据”和“处理数据的机制”,面向对象方法将软件视为一组互动的对象,将数据视为对象间传递的消息,这些工程科学方法的思路和原则可以借鉴。
借鉴上述软件工程方法,从法律实践考虑,建议用以下 6 要素构造条款语句,以表达软件功能:“角色、输入数据的来源、输入数据的内容、数据处理机制、处理后的数据去向、处理后的数据内容”。就是说,用上述 6 个要素构造一条语句,去描述一个功能。本质上,就是将模型图转化为形式化语言。
例如,受托开发一套人力资源管理软件,需要新员工登记功能,由人力资源部职员将新员工的信息记录在系统中。在需求说明书中,合同条款可以这样表达:“人力资源专员将系统外部的新员工信息录入存储至系统内”。分解这个语句,“角色”是“人力资源专员”,“输入数据的来源”是“系统外部”,“输入数据的内容”是“新员工信息”,“数据处理机制”是“录入存储”,“处理后的数据去向”是“系统内”,“处理后的数据内容”仍然是“新员工信息”(因为录入存储的信息内容无增减,没发生改变)。
(三)表达软件功能时,禁止类比表达。本质上,需求分析是表达一个“目前不存在的软件”未来的功能和样式,客户脑海中可能已经具备了某种形象,他们可能会以类比的方式向开发者表达功能,使用“我的软件要有……功能,就像……一样”这类语句。
例如,客户要开发一个“葡萄酒网上商场”,客户希望软件具备“优惠券功能”,客户可能会说“我的软件要有优惠券功能,就像京东和淘宝一样”。
律师、法务要对此特别警觉,绝对不能将类似“类似京东和淘宝的优惠券”这种类比性语句写入需求说明书。
首先,需求分析人员几乎不可能短时间搞清楚“京东、淘宝等商城优惠券的所有适用规则和所有约束规则”。再者,由于京东、淘宝等软件可能和该“葡萄酒网上商场”存在基础结构差异,就如同建筑地基不同一样,某些在京东、淘宝能实现的功能,在该“葡萄酒网上商场”可能无法实现,或者虽然能够实现,但会增加巨量的开发成本和工作量。
此外,当客户使用类比方式表达功能时,通常是参照其他成熟软件的功能,这种类比语句一旦出现在需求说明书中,违约风险会急剧增加,一定要多加注意。
(四)需求说明书中,尽量避免涉及界面元素。界面元素是指软件的可视元素,例如窗口、按钮的形状、尺寸、颜色等等。虽然几乎所有软件都必然会具备这些元素,而且界面也确实属于需求的一部分,但对于多数软件(游戏软件除外)来说,软件是否美观通常不重要。
另外,界面元素有时受限于功能逻辑本身,致使客户的个性化视觉要求无法完全满足,或者会无价值地增加开发成本。
比如,某个客户可能要求奇奇怪怪的按钮,而这些界面元素可能是无关功能的、吹毛求疵的,满足这类要求会意外增加法律风险。
妥善的办法是尽量不涉及界面要素,如果客户强烈要求,律师、法务有必要咨询技术人员,预先评估其可行性和开发成本。
五、其他注意事项
在软件工程实践中,开发者一方的工作人员经常与客户方人员进行工作对接,发生频繁交流,合同应约定专门条款接收关键信息。
例如,在软件开发过程中,客户向开发者提出软件需求变更;在验收测试中,客户提出软件存在错误(bug)。客户发出的这些信息都具有法律效果,可能暂停计算开发周期,可能影响计算软件错误修正期,从而可能间接触发违约条款。
如果没有专门的信息送达渠道,客户可能就会将重要信息发送到微信群聊中,当沟通信息量较大时,关键信息可能会被淹没,所以必须明确信息接收渠道。
例如:“提出对约定功能做出增加、变更、减少的,以及软件存在错误时,应当该信息发送至……@qq.com”。
前文已提到,要规范软件功能变更方式,比如“开发者同意增加、减少、修改软件功能必须经过书面签章同意”,然而在软件工程实践中,中小软件企业通常没有很规范的项目管理、版本控制,有时程序员认为某个变更非常微小,可能会擅自承诺同意客户的变更要求,这也会带来法律风险,需要加以规范。
例如约定“开发方工作人员,在与客户方人员对接沟通中,未经书面合同且签字盖章,擅自承诺对软件功能做出变更的,均不是有效承诺,开发方无须履行该承诺”。
在软件的测试验收环节,有时程序员会直接将“客户发现的软件异常”误认为是“软件错误”,直接在聊天沟通中承认“软件存在错误”,事实上该程序员可能仅负责某些模块,见木不见森林,可能未必了解错误的实质,这也会带来风险,也需要规范。
例如,条款可以约定“开发方工作人员,未以合同约定的途径向客户认可软件错误,以任何其他方式认可的软件异常均不是开发方认可的软件错误”。
六、结语
软件工程是一个广泛的领域,目标软件不同,风险侧重也会不同,随着软件工程理论和实践不断演进发展,也必然导致风险特征发生变化,合同也必然要与时俱进。
在设计合同时,应当与开发者的工作人员多沟通,尽可能了解开发者的工作流程、沟通模式、曾遇到的历史问题、曾发生的客户抱怨等等,这对提高合同质量一定是有益的。
软件开发合同设计指引
作者:尹欣来源:iCourt法秀

通过 Alpha 案例库检索计算机软件开发合同纠纷可以发现,软件开发合同就有由 2012 年的仅有 13 个案例到如今上千个案例,上涨飞速。